woocommerce/woocommerce-gateway-stripe

Variable subscriptions unaccounted for when creating mandates

Closed this issue · 2 comments

Describe the bug
Indian credit cards require autopay mandate to be setup. The plugin is currently setting up the mandate amount same as subscription price. If the user upgrades to a higher plan with more price, then the renewal fails.

This happens because the earlier mandate is not valid anymore.

To Reproduce
Steps to reproduce the behavior:

  1. Create variable subscription with 2 variations with prices ₹1,000/mon and ₹2,000/moon.
  2. First buy ₹1,000/mon subscription on say 1st of the month. This will setup autopay mandate of ₹1,000.
  3. Now upgrade to the ₹2,000/mon subscription in the middle of the month. Switch will happen successfully but the autopay mandate is still ₹1,000.
  4. On the renewal day the payment will fail as mandate amount is less than ₹2,000.

Expected behavior
New mandate should be set during switching, that way the switching will happen without failing.

Environment (please complete the following information):

  • WordPress Version: 6.5.5
  • WooCommerce Version: 9.0.2
  • Stripe Plugin Version: 8.4.0
  • WooCommerce Subscriptions Plugin Version: 6.4.0

I think the issue is here:

https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8.4.0/includes/compat/trait-wc-stripe-subscriptions.php#L702

Setting $mandate_options['amount_type'] to fixed when there's a single subscription doesn't take into account that (depending on the merchant's settings) subscriptions can be switched to a higher-cost variation.

We should probably be creating mandates for variable subscription products with $mandate_options['amount_type'] set to maximum. More about this here.

In fact, since variable subscription products can also have different billing intervals between variations, it doesn't make sense to set $mandate_options['interval'] to the billing period either! Maybe we should just do:

$mandate_options['amount_type'] = 'maximum';
$mandate_options['interval']    = 'sporadic';

... for ALL orders containing a subscription? What would be the downside?

I did confirm in testing that setting amount_type to maximum and interval to sporadic lets me upgrade a subscription without an error. However, I do still get an email asking me to go back to the site and auth with 3DS, but this is expected and there's no way around it.

Exactly, this is bang on solution. When can this be added?