Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
175 stars 69 forks source link

PayPal Standard Subscription keep renewing after deactivating WooCommerce Subscriptions #3463

Open AashikP opened 2 years ago

AashikP commented 2 years ago

Describe the bug

By default, WooCommerce Payments Subscriptions will automatically switch Subscriptions created via all other payment methods to Manual Renewals. However, with PayPal Standard Subscriptions (No RT), we see a behavior where Subscription details say Manual Renewals, and keeps creating pending renewal orders and setting the Subscription to on-hold. But the Subscription itself keeps renewing with PayPal Standard, and then re-activating the now on-hold Subscription.

To Reproduce

  1. Install WooCommerce Subscriptions and WooCommerce Payments
  2. Create a Subscription product that renews daily
  3. Make sure PayPal Standard has no Reference Transactions enabled. You can use add_filter( 'wooocommerce_subscriptions_paypal_reference_transactions_enabled', '__return_false' );
  4. Purchase the product via PayPal Standard
  5. Disable WooCommerce Subscriptions
  6. Notice that WooCommerce Payments takes over, and switches the Subscription renewal to Manual
  7. Also notice that it creates Pending Renewal Orders for customers to manually pay for the order, and puts the Subscription on-hold.
  8. However, the original Subscription with PayPal never really canceled, so it keeps renewing via PayPal, and as soon as the IPN notification is received, the Subscription on the store is set to Active

Actual behavior

Subscription is placed on-hold -> Subscription received IPN notification from PayPal -> Subscription is set to active

Screenshots

product

Subscription-details

related-orders

notes

Expected behavior

Either WooCommerce Payments should not set PayPal Standard renewals to manual, or it should cancel the Subscription with PayPal so that customers can manually pay for the renewal.

The former would be a better experience for the customers, but will have a different approach as compared to other payment method Subscriptions, which are placed on Manual orders.

Desktop (please complete the following information):

Smartphone (please complete the following information):

N/A

Additional context

Originally discussed in p1638502890093300/1637789842.451300-slack-C7U3Y3VMY

brianyu28 commented 2 years ago

I was looking into this one today, and noticed the following behavior: If I have a PayPal Standard subscription, when I disable WC Subscriptions and enable WCPay, the subscription appears as "manual renewal" but all the PayPal subscription metadata is still stored on the order. When I re-enable WC Subscriptions and disable WCPay, the subscription shows up as PayPal again as though nothing had happened. On the PayPal side, the subscription is listed as "Active" through this whole process.

@haszari, do you know what the expected behavior is here? When WC Subscriptions is disabled, should PayPal standard subscriptions be cancelled (or paused)?

haszari commented 2 years ago

I was looking into this one today, and noticed the following behavior: If I have a PayPal Standard subscription, when I disable WC Subscriptions and enable WCPay, the subscription appears as "manual renewal" but all the PayPal subscription metadata is still stored on the order. When I re-enable WC Subscriptions and disable WCPay, the subscription shows up as PayPal again as though nothing had happened. On the PayPal side, the subscription is listed as "Active" through this whole process.

Thanks for confirming @brianyu28 - this could potentially cause problems for merchants.

@haszari, do you know what the expected behavior is here? When WC Subscriptions is disabled, should PayPal standard subscriptions be cancelled (or paused)?

Good question. I think a merchant could expect either behaviour depending on the circumstances, e.g. disabling WC Subscriptions permanently vs. temporarily. We may need to give merchants more control here, either with docs or facility to assist with the downgrade.

haszari commented 2 years ago

@james-allan This issue could be included in upcoming downgrade scope focus.

james-allan commented 2 years ago

Thanks for your investigation @brianyu28.

The subscription being considered manual renewal programatically (opposed to deleting or changing data) after deactivating the plugin had the added benefit of being easily switched back later if the merchant switched the plugin back on.

However, the problem with that approach is that it has a number of issues for payment gateways like PayPal Standard who keep the subscription schedule ($subscription->payment_method_supports( 'gateway_scheduled_payments' ) ).

  1. PayPal needs to be notified that the payment method has changed if it isn't it will continue.
  2. It has to be notified prior to renewal or ASAP - it cannot be done JIT.
    • By the time PayPal sends the notification (IPN) to the store to record that a payment has been taken, it's too late. That payment has been taken and will need to be recorded in WooCommerce.

So unfortunately the programatically set to manual renewal approach is pretty much incompatible with gateways like PayPal Standard. IMO there are two approaches we could go with:

  1. As you mentioned, cancel or suspend the PayPal Standard subscriptions (and other like payment methods) after the plugin is deactivated. Reactivating the Subscriptions plugin would need to either reactivate them or simply just leave them as manual - they are no longer PayPal and will need to be re-set up by the customer.
    • This would need to be done via a background job/script.
    • We'd need to work out how this would handle PayPal renewal payments that could occur while we're in the process of to downgrading them. It's an unlikely event but possible.
  2. They stay PayPal Standard for 1 more renewal and then get cancelled and set to manual.

Option 1 has the benefit of maintaining subscriptions-core integrity - if you disable the plugin, WC Payments is the only subscription eligible payment method.

However, accidental or temporary deactivation of the plugin will be more impactful - ie instead of programatically changing subscription payment methods, it's actually changing or potentially corrupting data.

Option 2 has the benefit of being quickly reversed. If you accidentally deactivate the plugin, reactivating the plugin won't need to wrangle the scheduling or cancelling background scripts since the migration happens at the point of PayPal payment.

The issue here is that it might be confusing that some subscriptions are transferred to manual renewal immediately, others are still PayPal Standard (until next renewal) and communicating that nuance to merchants will be difficult. It only really makes sense if you have an understanding of the limitations and differences between the different PayPal options. It also has the issue of needing to support PayPal code inside subscriptions-core indefinitely.


My preference would be to go with option 1, however that comes with some hurdles will need to still jump. Eg communicating that via the deactivate plugin modal etc.

haszari commented 2 years ago

Thanks for the insights and options @james-allan !

Option 1 - batch migrate - seems like a good robust option. If we do go this way I'd like to ensure we give the merchant enough info about what's happening, and a way to control it. Maybe we could implement the processing so it can be manually triggered, with a way to see progress and when it's done (something super basic). And then as a follow up trigger it automatically if we think that's safe and useful for merchants.

Option 2 - seems reasonable to me also. I like the fact that it avoids the complexity and risk of a background migration job. As you mentioned, there's some unavoidable complexity with WC Pay subscriptions interacting with PayPal; we probably can't abstract that away from merchants completely. Maybe there are ways we can mitigate that complexity with docs, guidance for merchants, so they are empowered to deal with it.

haszari commented 2 years ago

@brianyu28 - if you are in progress on this or have thoughts/ideas - please comment. Since this is somewhat complex, I've added this to the scope for Helix's next cycle, so unassigned you for now.

brianyu28 commented 2 years ago

Sounds good, thanks for letting me know @haszari! I think either option is reasonable if it's communicated clearly when WC Subscriptions is deactivated. I imagine the behavior might also change depending on whether WCPay is active when WC Subscriptions is deactivated — if neither is active, then cancelling the subscription after the next renewal (Option 2) doesn't seem possible since subscriptions-core won't be loaded at all when the renewal happens.

haszari commented 2 years ago

I imagine the behavior might also change depending on whether WCPay is active when WC Subscriptions is deactivated — if neither is active, then cancelling the subscription after the next renewal (Option 2) doesn't seem possible since subscriptions-core won't be loaded at all when the renewal happens.

That's an insightful comment đŸ€” .

Perhaps the responsibility for handling these subscriptions is in WooCommerce Subscriptions. So rather than implement migration/downgrade code in WCPay, the migration code should be in WooCommerce Subscriptions, so the merchant can pause/disable/cancel (migrate) subscriptions if they need to deactivate WC Subscriptions for any reason.

@james-allan What do you think - maybe this type of migration issue belongs with WooCommerce Subscriptions rather than WCPay?

james-allan commented 2 years ago

It can't be in WooCommerce Subscriptions since that's the plugin the user has deactivated. Unless we plan on leaving the plugin active while we cancel these subscriptions.

I imagine the behavior might also change depending on whether WCPay is active when WC Subscriptions is deactivated — if neither is active, then cancelling the subscription after the next renewal (Option 2) doesn't seem possible since subscriptions-core won't be loaded at all when the renewal happens.

Yeah you're 100% correct. If a user chooses to deactivate WC Subscriptions and also doesn't have WC Payments active, then the PayPal subscriptions won't get cancelled. This is inline with the current behaviour where deactivating the Subscriptions plugin basically does nothing.

WC Payments active at the time of WC Subscriptions deactivation:

WC Payments inactive at the time of WC Subscriptions deactivation:

haszari commented 2 years ago

It can't be in WooCommerce Subscriptions since that's the plugin the user has deactivated. Unless we plan on leaving the plugin active while we cancel these subscriptions.

Yeah you're 100% correct. If a user chooses to deactivate WC Subscriptions and also doesn't have WC Payments active, then the PayPal subscriptions won't get cancelled. This is inline with the current behaviour where deactivating the Subscriptions plugin basically does nothing.

Just to clarify what I meant about "the responsibility for handling these subscriptions is in WooCommerce Subscriptions".

We could add a downgrade/disable process to WC Subscriptions that the merchant can trigger manually before deactivating the plugin. Maybe this is not a big deal though, since it's effectively an existing gap in functionality, and it's probably rare use case (using PayPal subscriptions and migrating away from WC Subscriptions).