Skip to content

UR-4830: Fix Membership Renewal Reminder sent for subscriptions cancelled at period end - #1394

Open
saurab018 wants to merge 1 commit into
developfrom
UR-4830-membership-renewal-reminder-email-sent-to-users-with-cancelled-stripe-subscriptions-cancel-at-period-end-urm-cron-does-not-check-cancellation-flag
Open

UR-4830: Fix Membership Renewal Reminder sent for subscriptions cancelled at period end#1394
saurab018 wants to merge 1 commit into
developfrom
UR-4830-membership-renewal-reminder-email-sent-to-users-with-cancelled-stripe-subscriptions-cancel-at-period-end-urm-cron-does-not-check-cancellation-flag

Conversation

@saurab018

Copy link
Copy Markdown
Contributor

All Submissions:

Changes proposed in this Pull Request:

A member who cancels a subscription at period end still receives the Membership Renewal Reminder email, telling them they are about to be billed for a membership they already cancelled.

Cause

When a subscription is cancelled while the paid period is still running, we intentionally keep it active until the end date and record the cancellation in user meta instead:

// SubscriptionRepository::cancel_subscription_by_id()
if ( ! empty( $expiry_date ) && strtotime( $expiry_date ) > time() ) {
	update_user_meta( $subscription['user_id'], 'urm_pending_cancel_' . $subscription_id, $expiry_date );
} else {
	$this->update( $subscription_id, array( 'status' => 'canceled' ) );
}

daily_membership_renewal_check() then picks it up, because get_about_to_expire_subscriptions() filters on status and billing date only:

WHERE NOT wums.status = 'canceled'
AND DATE(wums.next_billing_date) = DATE('%s')

Nothing in the loop consults the urm_pending_cancel_<subscription_id> meta, so a cancelled-at-period-end membership matches and the reminder goes out.

Fix

Skip subscriptions that already carry the pending-cancel meta. This is the same guard daily_membership_expiring_soon_check() already has — it was applied there and missed here. Which of the two crons runs depends on user_registration_renewal_behaviour (automatic → renewal reminder, manual → expiring soon), so sites on automatic renewal hit the unguarded path.

Notification-only defect: no payment is taken and the subscription record is unaffected. Reported by a customer whose member cancelled on Stripe with cancel_at_period_end, then received the reminder on the period end date itself.

Closes # .

How to test the changes in this Pull Request:

  1. Enable membership with a recurring paid plan, and set Renewal Behaviour to Automatic with the Renewal Reminder email enabled.
  2. Register a member on the plan so a subscription with a future next_billing_date / expiry_date exists.
  3. Cancel the membership from My Account → Membership while the paid period is still running. Confirm the subscription stays active and urm_pending_cancel_<subscription_id> user meta is set (the admin list shows "Cancels <date>").
  4. Set the reminder window so the subscription falls inside it — e.g. user_registration_membership_renewal_reminder_days_before / _period such that today + window equals next_billing_date.
  5. Run urm_daily_membership_renewal_check (WP Crontrol, or wp cron event run urm_daily_membership_renewal_check).
  6. Before: the member receives the Membership Renewal Reminder. After: no email is sent.
  7. Regression check: repeat with a normal active subscription that was never cancelled — the reminder must still be sent as before.

Types of changes:

  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (modification of the currently available functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you successfully ran tests with your changes locally?
  • Have you updated the documentation accordingly?

Changelog entry

Fix - Membership Renewal Reminder email sent to members who had already cancelled at period end.

daily_membership_renewal_check() selected subscriptions using only status
and next billing date. A membership cancelled at period end stays active
until its end date, with the cancellation recorded in the
urm_pending_cancel_<subscription_id> user meta, so it still matched and
received a renewal reminder it will never act on.

Skip those, matching the guard daily_membership_expiring_soon_check()
already has.
@saurab018 saurab018 self-assigned this Aug 17, 2026
@saurab018
saurab018 requested a review from y000yal August 17, 2026 08:00
@lihsaa591

Copy link
Copy Markdown
Contributor

@tg-autopilot review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes renewal reminders being sent for subscriptions scheduled to cancel at period end.

Changes:

  • Skips reminders when pending-cancellation metadata exists.
  • Preserves reminders for active, non-cancelled subscriptions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants