Skip to content

Conversation

@lmcrean
Copy link
Contributor

@lmcrean lmcrean commented Sep 2, 2025

Problem Statement

When users cancel subscriptions before GoCardless payment is confirmed (2-7 day window), the status incorrectly shows "Pending Cancellation" instead of "Cancelled". This creates confusion as the payment hasn't been confirmed yet.

Root Cause

Two issues:

  1. Missing status synchronization between parent orders and subscriptions
  2. No check for payment confirmation status during user-initiated cancellations

Solution

1. Centralized Cancellation Handling

  • Added handle_subscription_cancellation() method in class-wc-gocardless-gateway.php
  • Handles webhook-based cancellations (payment/billing request cancelled)
  • Clears pending payment metadata consistently

2. Parent Order Status Sync

  • Added sync_parent_order_status() in class-wc-gocardless-gateway-addons.php
  • Updates parent order to "cancelled" when all subscriptions are cancelled
  • Ensures status consistency across orders and subscriptions

3. User-Initiated Cancellation with Payment Check

  • Added maybe_skip_pending_cancel_status() filter callback
  • Checks parent order's _gocardless_payment_status meta
  • Skips pending-cancel if payment not confirmed/paid_out
  • Forces immediate cancellation for unconfirmed payments

Expected Behavior

Scenario Payment Status User Cancels → Result
Payment confirmed confirmed / paid_out Pending Cancellation ✓
Payment unconfirmed pending_submission / submitted / pending_customer_approval Cancel immediately ✓

Testing

Manual Test:

  1. Create a subscription order (payment status will be pending_submission)
  2. User cancels subscription from My Account or wp-admin
  3. Verify subscription status = "Cancelled" (not "Pending Cancellation")
  4. Verify parent order status = "Cancelled"
  5. Check logs for: "Skipping pending-cancel for subscription #X..."

After Payment Confirmed:

  1. Wait for payment status to update to confirmed
  2. User cancels subscription
  3. Verify subscription status = "Pending Cancellation"

Files Changed

  • includes/class-wc-gocardless-gateway.php - Centralized cancellation handler
  • includes/class-wc-gocardless-gateway-addons.php - Parent sync + payment check filter

Related

PR #50 (webhook-based cancellation handling)
Fixes #78

Changelog entry

Fix - Inconsistent subscription status after cancellation.

…tatus synchronization

- Introduced a new method `handle_subscription_cancellation` to manage subscription cancellations consistently across orders.
- Added `sync_parent_order_status` method to update the parent order status when all associated subscriptions are cancelled.
- Updated existing cancellation logic to utilize the new centralized handling for improved maintainability.
@lmcrean
Copy link
Contributor Author

lmcrean commented Sep 3, 2025

Confirmed in unit testing, does anyone have access to trying on local machine with the paid subscription plugin? @diegocurbelo @peterwilsoncc @joemcgill @dkotter

@jeffpaul jeffpaul added this to the 3.0.0 milestone Sep 30, 2025
@jeffpaul jeffpaul requested a review from dkotter September 30, 2025 15:11
@jeffpaul jeffpaul linked an issue Sep 30, 2025 that may be closed by this pull request
@jeffpaul jeffpaul modified the milestones: 3.0.0, 3.0.1 Sep 30, 2025
dkotter
dkotter previously approved these changes Oct 1, 2025
Copy link
Collaborator

@iamdharmesh iamdharmesh left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the PR, @lmcrean. While reviewing the PR, I noticed that the issue report(#78) didn’t include the background details and all the necessary information (apologies for that). I’ve added additional context and details about the issue here.

While testing this PR, I also noticed that it doesn’t fully resolve the issue. Could you please review the additional information I’ve shared and confirm?

Thanks again for your contribution!

lmcrean and others added 4 commits October 4, 2025 11:25
…h unconfirmed payments

- Introduced a new method `maybe_skip_pending_cancel_status` to handle subscription cancellations more effectively.
- This method ensures that subscriptions are cancelled immediately if the associated GoCardless payment is unconfirmed, aligning behavior with user expectations.
- Added logging for cases where pending-cancel is skipped due to unconfirmed payment status.
@lmcrean
Copy link
Contributor Author

lmcrean commented Oct 4, 2025

Thanks @iamdharmesh for the context! I can see that the initial PR handled webhook-based cancellations but missed user-initiated cancellations with unconfirmed payments.

So I've added a fix for the missing piece. This completes the behavior described in your summary:

  • Payment confirmed → User cancels → Pending Cancellation
  • Payment unconfirmed → User cancels → Cancel immediately (now fixed)

Let me know if you'd like me to adjust anything

Copy link
Collaborator

@iamdharmesh iamdharmesh left a comment

Choose a reason for hiding this comment

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

Thanks for the changes @lmcrean. I have added some more comments could you please check it once?

…sitions

- Updated `sync_parent_order_status` method to immediately cancel subscriptions with unconfirmed payments during pending-cancel transitions.
- Removed the `maybe_skip_pending_cancel_status` method as its functionality is now integrated into the cancellation logic.
- Improved logging for better tracking of subscription cancellations related to payment confirmation status.
@lmcrean
Copy link
Contributor Author

lmcrean commented Oct 25, 2025

thanks @iamdharmesh could i get your review please? Addressed your suggestions

@jeffpaul jeffpaul requested a review from iamdharmesh October 29, 2025 02:15
Copy link
Collaborator

@iamdharmesh iamdharmesh left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the changes @lmcrean and sorry for the delayed review. I was on vacation, just came back this week. Changes now looks good. However, added some feedback to check. Could you please check it once. Thanks.

…ion checks

- Enhanced the `sync_parent_order_status` method to check the most recent order's payment status (parent or renewal) during pending-cancel transitions.
- Removed the centralized `handle_subscription_cancellation` method to streamline cancellation handling directly within the order processing logic.
- Improved logging messages for clarity regarding subscription cancellations due to unconfirmed payments.
- Updated the order check condition to ensure that the variable is an instance of `WC_Abstract_Order` before proceeding with payment status retrieval.
- This change improves the robustness of payment confirmation checks during subscription processing.
- Updated the logic to fetch the payment status directly from the GoCardless API during pending-cancel transitions, improving reliability by addressing potential webhook delays.
- Added error handling and logging for cases where payment retrieval fails, ensuring safe defaults are maintained.
@lmcrean
Copy link
Contributor Author

lmcrean commented Nov 3, 2025

@iamdharmesh thanks as always for the codebase insights. I have addressed all points made; see resolved comments.

Ready for next review.

@vikrampm1
Copy link
Collaborator

@iamdharmesh this is back for your re-review when you get a moment.

Copy link
Collaborator

@iamdharmesh iamdharmesh left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the PR @lmcrean. I have made some minor changes and this is good to go now.

@iamdharmesh iamdharmesh requested a review from dkotter November 25, 2025 11:36
@qasumitbagthariya
Copy link
Collaborator

Regression / Smoke Test Report ✅

Tested with Archive File created via "php woorelease.phar build repo_URL" (Composer version 2.8.4, npm version 10.8.2, node version 20.18.1)

Status- Working expected with Plugin Archive/Zip file same as fix specific branch.

Screen.Recording.2025-12-17.at.2.42.57.AM.mov

Testing Environment

Details
  • WordPress: 6.9
  • Theme: Storefront 4.6.2
  • Theme: Twenty Twenty-Five 1.4
  • WooCommerce - 10.4.0
  • PHP: 8.0.30
  • Web Server: Nginx 1.20.2
  • Browser: Chrome
  • OS: macOS 15.2
  • Branch: smoke-testing

Next Step- Ready to Merge 🚀

@vikrampm1 vikrampm1 merged commit 050c9ca into gocardless:develop Dec 17, 2025
6 of 7 checks passed
@vikrampm1 vikrampm1 mentioned this pull request Dec 17, 2025
25 tasks
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.

Inconsistent subscription status display after cancellation

6 participants