* FEATURE: Upgraded the email template editor to the standard WordPress visual/text editor with built-in Liquid syntax autocomplete for variables, tags, and filters. #3695 (@dparker1005)
* FEATURE: Added a new `[pmpro_membership_level]` shortcode for displaying membership level details. #3087 (@kimcoleman)
* ENHANCEMENT: Added Divi 5 compatibility for PMPro module-level restrictions and no-access message handling. #3620 (@JarrydLong)
* ENHANCEMENT: Added a new `level_group_id` email template variable to every email template class that exposes `membership_id`. #3684 (@kimcoleman)
* ENHANCEMENT: Allowed shortcodes in the account page message. #3682 (@kimcoleman)
* ENHANCEMENT: Removed the misleading "Advanced Settings" hint from the no-access message controls. #3699 (@dparker1005)
* ENHANCEMENT: Clarified the user field meta key hint on the user field settings page. #3698 (@kimwhite)
* ENHANCEMENT: Added an Add On icon for the MemberPress Migration Toolkit. (@kimcoleman)
* BUG FIX/ENHANCEMENT: Now hiding the recurring trial settings on membership level and discount code edit pages when the active gateway doesn't support recurring trials. #3628 (@dparker1005)
* BUG FIX/ENHANCEMENT: Added a fallback for email logging when SMTP plugins (e.g. Gravity SMTP) bypass the `wp_mail_succeeded` and `wp_mail_failed` actions. #3697 (@andrewlimaza)
* BUG FIX: Cleaned up orphaned membership level relationships when a level is deleted. #3693 (@dparker1005)
* BUG FIX: No longer shows the membership confirmation message when the order has not been confirmed. #3682 (@kimcoleman)
* BUG FIX: Fixed a fatal error on the Membership Billing page for logged-out requests. #3694 (@flintfromthebasement)
* BUG FIX: Fixed the Orders list table appearing blank on mobile by setting the order code as the default primary column. #3696 (@dparker1005)
* BUG FIX: Cleared stale card information when a recovered Stripe payment uses a non-card payment method. #3703 (@dparker1005)
* REFACTOR: Removed unused `pmpro_userfields_get_group` and `pmpro_userfields_get_field` AJAX handlers. #3672 (@dparker1005)
* DEPRECATED: Deprecated the credit card expiring email template. #3688 (@dparker1005)
* DEPRECATED: The Membership Billing page no longer writes `pmpro_b*` user meta on save, and the email field has been removed from that page. #3668 (@dparker1005)
* BUG FIX/ENHANCEMENT: Skip the `pmpro_visit` cookie when `WP_CACHE` is active so page caches like Surge, Cloudflare, Varnish, and WP Super Cache aren't bypassed on anonymous front-end requests. Added a new `pmpro_set_visit_cookie` filter to override the default behavior. #3690 (@flintfromthebasement)
* BUG FIX: Fixed Stripe recurring orders silently saving `tax = 0` after the Stripe API version bump by deriving tax from `invoice->total_excluding_tax` instead of the deprecated `invoice->tax`. #3685 (@dwanjuki)
* BUG FIX: Fixed Site Health reporting a false-positive Action Scheduler library conflict on Windows hosts by normalizing the library path before the conflict check. #3687 (@dparker1005)
* BUG FIX: Fixed button icons no longer being inline in the WordPress 7.0 admin and the "Show" label floating to the right of the levels dropdown on the Members List screen. #3689 (@RachelRVasquez)
* SECURITY: Added a nonce check to the Update Billing Information page to prevent CSRF, and tightened the gate so enforcement only skips on sites explicitly opted into a pre-3.7.3 custom billing template. The billing template version has been bumped to 3.7.3. #3671 (@dparker1005)
* SECURITY: Tightened the checkout page nonce enforcement gate so it only skips on sites explicitly opted into a pre-3.0 custom checkout template, closing a gap where sites with a pre-3.0 custom `checkout.php` in their theme could bypass nonce checks without opting in. #3674 (@dparker1005)
* ENHANCEMENT: Added new action hooks to the subscriptions panel of the Edit Member screen and the single subscription view. #3666 (@kimcoleman)
* ENHANCEMENT: Added nonce checks to read-only admin AJAX handlers (`pmpro_orders_print_view`, `pmpro_get_order_json`, `login_report_csv`, `sales_report_csv`, `membership_stats_csv`) for consistency with other admin AJAX endpoints. #3673 (@dparker1005)
* ENHANCEMENT: Added the new `pmpro_use_advisory_locks` filter as a system-wide escape hatch to disable MySQL advisory locking on hosts where persistent MySQL sessions or other environment quirks cause stuck locks. #3649 (@dparker1005)
* ENHANCEMENT: Replaced the vague "Stripe dashboard settings" wording with a direct link to the Stripe Radar rules page in the billing address field description. #3677 (@dparker1005)
* BUG FIX: Prevented concurrent Stripe webhook deliveries from racing on the same order by introducing a MySQL advisory lock around webhook processing. This fixes cases where "at least once" Stripe delivery from multiple infrastructure nodes could create duplicate membership rows or cancel a freshly-created subscription. #3649 (@dparker1005)
* BUG FIX: Fixed the Old Members CSV export to exclude users who currently have any active membership, matching the logic already used by the expired and cancelled filters. #3680 (@dwanjuki)
* BUG FIX: Fixed a PHP warning and a missing payment transaction ID when Stripe checkout sessions complete asynchronously (e.g. Bank Transfer), where the PaymentIntent has no `latest_charge` at completion time. #3655 (@dwanjuki)
* BUG FIX: Honored the configured currency decimals in `pmpro_get_price_info()`'s `amount_string` so zero-decimal currencies (JPY, KRW, VND, UAH, ALL) no longer produce strings like "25.00" that PayPal billing rejects. Also fixed `pmpro_get_currency()` so it actually honors the `$currency` parameter it advertises. #3676 (@dparker1005)
* BUG FIX: Allowed updating billing for subscriptions without a successful order on file, so manually-linked subscriptions in the admin no longer redirect users away from the billing page. #3667 (@dparker1005)
* BUG FIX: Fixed the Restricted Files protection self-test reporting "Unable to determine" on sites with no member uploads, by writing a non-dotfile marker (`pmpro-protection-test.txt`) alongside the existing `.htaccess`. #3675 (@dalemugford)
* Fix: Pro Rate - a notice being thrown sometimes
* Misc: Invoices - allow display of plan item row on Invoice for 0 amounts
* Misc: Pay What You Want - Add a log entry on the subscription with the chosen price by the user
* SECURITY: Tightened ownership check in the `/pmpro/v1/order` REST permission callback to bail early for anonymous requests, require a non-empty order ID, and use a strict integer comparison. #3643 (@flintfromthebasement)
* SECURITY: Scoped the `/pmpro/v1/quick_search` users meta lookups to custom profile fields by skipping internal WP/plugin meta keys. Added the `pmpro_rest_api_quick_search_meta_key_blocklist` filter so sites can extend the blocklist. #3644 (@flintfromthebasement)
* SECURITY: Fixed a non-functional capability guard in `PMPro_Field_Group::save_fields()` where a literal string comparison made the `current_user_can( 'edit_user' )` check unreachable. #3645 (@flintfromthebasement)
* ENHANCEMENT: Reworked the Email Settings and Security Settings admin pages to detect the active email sending method and security provider, surface that information in Site Health, recognize PMPro Max as a provider, and remove the legacy built-in SendWP integration. #3656 (@kimcoleman)
* ENHANCEMENT: Renamed the Builder and Plus Add Ons to Max throughout the admin and labeled all paid Add Ons under the new Premium license tier. #3650 (@dparker1005)
* ENHANCEMENT: Added the new PayPal Gateway Add On to the Payment Gateway settings page, surfacing it as "Enabled (via Add On)" when active as a secondary gateway. #3657 (@dparker1005)
* ENHANCEMENT: Added new filters for avatar upload location and render location to support multisite installations. #3648 (@kimcoleman)
* ENHANCEMENT: Updated the Design Settings page link to a direct URL so tracking parameters work without a redirect. #3625 (@kimwhite)
* ENHANCEMENT: Added/updated Add On icons including a new MailerLite icon for an upcoming Add On. #3627, #3652 (@kimcoleman)
* BUG FIX/ENHANCEMENT: Fixed three bugs that caused member CSV export downloads to return 403/404: deferred export record cleanup until after the file is served, extended download token TTL to 7 days and hardened the URL builder when no token is available, and prevented zero-record exports from creating a ghost "complete" state. Introduced the `pmpro_restricted_file_served` action and buffered handler output to avoid corrupting the response. #3637 (@dalemugford)
* BUG FIX: Fixed a deprecated `pmpro_changeMembershipLevel()` call when deleting a WP user. #3660 (@kimwhite)
* BUG FIX: Fixed deprecation notices in `pmpro_cleanPhone()` when the phone value is `null`. #3654 (@dwanjuki)
* BUG FIX: Fixed the All Levels member export producing duplicate rows and omitting members with higher user IDs in large exports. #3632 (@flintfromthebasement)
* BUG FIX: Fixed the `checkbox_grouped` field input not receiving the correct CSS selectors. #3646 (@kimcoleman)
* BUG FIX: Skipped content visibility controls for unsupported blocks in widget editors to prevent JS errors. #3653 (@dwanjuki)
= 3.7.1 - 2026-03-25 =
* BUG FIX: Fixed some admin pages not saving due to POST redirect in list table referer cleanup. #3624 (@kimcoleman)
* BUG FIX: Fixed PHP 8.1 deprecation warnings in restricted files functions on Windows servers with misconfigured upload directories. #3623 (@flintfromthebasement)
* DEPRECATED: Deprecated the PayPal Express gateway. PayPal is retiring the NVP/SOAP API that PayPal Express relies on. A new PayPal integration is coming soon. #3622 (@dparker1005)
* DEPRECATED: Renamed the Website Payments Pro gateway slug from `paypal` to `paypalwpp` to free the `paypal` slug for the upcoming PayPal REST API Add On. #3622 (@dparker1005)
* BUG FIX: Fixed some admin pages not saving due to POST redirect in list table referer cleanup. #3624 (@kimcoleman)
* BUG FIX: Fixed PHP 8.1 deprecation warnings in restricted files functions on Windows servers with misconfigured upload directories. #3623 (@flintfromthebasement)
* DEPRECATED: Deprecated the PayPal Express gateway. PayPal is retiring the NVP/SOAP API that PayPal Express relies on. A new PayPal integration is coming soon. #3622 (@dparker1005)
* DEPRECATED: Renamed the Website Payments Pro gateway slug from `paypal` to `paypalwpp` to free the `paypal` slug for the upcoming PayPal REST API Add On. #3622 (@dparker1005)
* FEATURE: Added native profile picture (avatar) support, allowing members to upload custom avatars managed entirely within PMPro instead of relying on Gravatar. #3597 (@ideadude)
* FEATURE: Added a Quick Search feature for navigating Memberships admin pages. #3563 (@dparker1005)
* FEATURE: Added Liquid-style template rendering for email bodies with support for variables, filters, and conditionals. #3584 (@dparker1005)
* FEATURE: Added email logging for all emails sent by PMPro. The new `pmpro_should_log_email` filter can be used to enable email logging for non-PMPro emails as well. #3573, #3581 (@dparker1005)
* ENHANCEMENT: Added sidebar filter panels for the orders and subscriptions admin pages with support for level, status, date range, discount code, gateway, and total filters. #3602 (@dparker1005)
* ENHANCEMENT: Added To, CC, and BCC settings to the Email Templates editor. #3588 (@kimcoleman)
* ENHANCEMENT: Members and orders CSV exports now use Action Scheduler for improved reliability on large datasets. #3543 (@dalemugford)
* ENHANCEMENT: Added optional Action Scheduler support for deferrable webhook events. #3589 (@dparker1005)
* ENHANCEMENT: Added Site Health critical issue notification when plugins are using incorrect folder names. #3553 (@andrewlimaza)
* ENHANCEMENT: Added a restricted directory check to detect and report issues with the protected files directory. #3557 (@dalemugford)
* ENHANCEMENT: Improved support for reCAPTCHA v3 with score validation, defaulting to 0.5 and customizable via the `pmpro_recaptcha_v3_min_score` filter. #3564 (@andrewlimaza)
* ENHANCEMENT: Adjusted the Update Billing page to no longer automatically redirect away to the account page. #3566 (@andrewlimaza)
* ENHANCEMENT: Updated the Subscriptions admin screens to match the orders admin screens for view, edit, and link styling. #3568 (@kimcoleman)
* ENHANCEMENT: Removed use of the deprecated `SQL_CALC_FOUND_ROWS` modifier across all queries. #3571 (@dparker1005)
* ENHANCEMENT: Consolidated membership signup and cancellation queries for improved performance on dashboard reports. #3574 (@dparker1005)
* ENHANCEMENT: Now caching the Members Per Level report for improved dashboard performance. #3580 (@dparker1005)
* ENHANCEMENT: Added `membership_id` as a default column in the Members List CSV export. #3604 (@andrewlimaza)
* ENHANCEMENT: Now supporting `light-dark` values for contextual message CSS custom properties. #3606 (@kimcoleman)
* ENHANCEMENT: Added PMPro icon to the admin menu and updated the top menu bar to use an icon with screen reader text. #3607 (@kimcoleman)
* BUG FIX/ENHANCEMENT: Updated the checkout form submit handler to improve reliability of payment processing. #3545 (@dwanjuki)
* BUG FIX/ENHANCEMENT: Updated the capability check for viewing admin user fields to use `pmpro_edit_members`. #3561 (@dparker1005)
* BUG FIX: Fixed dependencies for the content visibility block component to prevent enqueue issues. #3538 (@dparker1005)
* BUG FIX: Fixed a default height prop warning in block editor components. #3540 (@dwanjuki)
* BUG FIX: Fixed a console warning in WordPress 6.3+ by moving block asset enqueuing to the `enqueue_block_assets` hook. #3549 (@andrewlimaza)
* BUG FIX: Fixed slashed level names displaying with backslashes in the setup wizard. #3617 (@dparker1005)
* REFACTOR: Refactored the Stripe webhook handler into a new `PMPro_Stripe_Webhook_Handler` class. #3589 (@dparker1005)
* REFACTOR: Removed unused test scripts. #3600 (@dparker1005)
* DEPRECATED: Marked the Subscription Check Add On as deprecated on the Add Ons page. #3601 (@dwanjuki)
* DEPRECATED: Reading webhook status via `pmpro_doing_webhook()` is now deprecated. Use `pmpro_doing_webhook( $gateway, true )` for write mode only. #3603 (@dparker1005)
* DEPRECATED: The `pmpro_before_members_list_csv_export` and `pmpro_after_members_list_csv_export` actions are deprecated and no longer fired. #3543 (@dalemugford)
* DEPRECATED: Removed bundled core translation files to reduce the shipped plugin package size. #3605 (@dparker1005)
* SECURITY: Added capability and nonce checks to Stripe webhook AJAX management endpoints. #3615 (@dparker1005)
* SECURITY: Added shared-secret token validation for the deprecated Authorize.net ARB Silent Posts integration with a configurable `pmpro_authnet_silent_post_token` option in gateway settings. #3598 (@dparker1005)
* BUG FIX: Fixed an operator precedence bug causing corechart.js to load on all report pages. #3609 (@flintfromthebasement)
* BUG FIX: Fixed an "Attempt to read property ID on null" warning in display post states. #3599 (@dwanjuki)
* SECURITY: Gated the unverified Stripe webhook event fallback behind a new `pmpro_stripe_webhook_allow_unverified_post_event` filter, which defaults to `false`. #3592 (@dparker1005)
* ENHANCEMENT: Updated links to the Member Directory and Podcasting Use Case landing pages and hubs. #3593 (@kimcoleman)
* ENHANCEMENT: Added a new `pmpro_memberships_widget_periods` filter to allow customizing the time periods shown in the Memberships Report widget. (@kimcoleman)
* ENHANCEMENT: Added a new icon for the PMPro Kit Add On. #3575 (@kimcoleman)
* ENHANCEMENT: Now clearing the object cache when user fields are created, updated, or deleted to ensure changes show immediately when using persistent object caching. #3565 (@dalemugford)
* ENHANCEMENT: Updated the WP Fusion Lite integration through v3.47.6. #3583 (@dparker1005)
* BUG FIX/ENHANCEMENT: Now ignoring PayPal error code 11556 when cancelling a subscription that is already inactive to avoid unnecessary admin notifications. #3572 (@dparker1005)
* BUG FIX: Fixed an issue where the field group description was not showing due to an incorrect variable reference. #3591 (@mircobabini)
* BUG FIX: Fixed an issue where failed Stripe recurring payment orders were missing card info and billing address data. #3590 (@dparker1005)
* BUG FIX: Fixed an issue where the membership level billing amount could be recalculated incorrectly when processing checkout via webhook, potentially losing discount code pricing. #3585 (@dparker1005)
* BUG FIX: Fixed an issue where the timestamp for new orders created in the admin could default to 1970 when the site timezone is not UTC. #3582 (@dparker1005)
* BUG FIX: Resolved PHP 8.5+ deprecation warnings for non-canonical cast names. #3560 (@dwanjuki)
* ENHANCEMENT: Adding a new `!!order_url!!` email template variable to checkout email templates. #3555 (@kimcoleman)
* ENHANCEMENT: Now limiting failed payment emails to be sent a maximum of once daily per subscription. #3552 (@dparker1005)
* ENHANCEMENT: Now cleaning up library conflict records that are older than 7 days. #3554 (@dalemugford)
* BUG FIX/ENHANCEMENT: Discount codes now expire at the end of the date set as the "Expiration Date" instead of at the start of that date. #3559 (@dparker1005)
* BUG FIX/ENHANCEMENT: Now ignoring Stripe `charge.failed` webhook events for subscriptions that have already been cancelled in Stripe which could interfere with processing the subsequent `customer.subscription.deleted` webhook event. #3556 (@dparker1005)