s2Member sending request to Cancel Subscription to Stripe

He’s back :partying_face:

I’ll also keep an eye from now on. :innocent:

So, I am unsure if it will work, but this is my test, where I intentionally neuter Stripe’s Cancellation routines:

Inside the folder /wp-content/plugins/s2member-pro/src/includes/classes/gateways/stripe I modified a few files…

stripe-cancellation-in.inc.php

										if(is_array($ipn_signup_vars = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars()))
										{
											/* Deactivated Section Below and changed the Log Return to Reflect That
											$ipn['txn_type']   = 'subscr_cancel';
											$ipn['subscr_cid'] = $ipn_signup_vars['subscr_cid'];
											$ipn['subscr_id']  = $ipn_signup_vars['subscr_id'];
											$ipn['custom']     = $ipn_signup_vars['custom'];

											$ipn['period1'] = $ipn_signup_vars['period1'];
											$ipn['period3'] = $ipn_signup_vars['period3'];

											$ipn['payer_email'] = $ipn_signup_vars['payer_email'];
											$ipn['first_name']  = $ipn_signup_vars['first_name'];
											$ipn['last_name']   = $ipn_signup_vars['last_name'];

											$ipn['option_name1']      = $ipn_signup_vars['option_name1'];
											$ipn['option_selection1'] = $ipn_signup_vars['option_selection1'];

											$ipn['option_name2']      = $ipn_signup_vars['option_name2'];
											$ipn['option_selection2'] = $ipn_signup_vars['option_selection2'];

											$ipn['item_name']   = $ipn_signup_vars['item_name'];
											$ipn['item_number'] = $ipn_signup_vars['item_number'];

											$ipn['s2member_paypal_proxy']              = 'stripe';
											$ipn['s2member_paypal_proxy_use']          = 'pro-emails';
											$ipn['s2member_paypal_proxy_verification'] = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen();

											c_ws_plugin__s2member_utils_urls::remote(home_url('/?s2member_paypal_notify=1'), $ipn, array('timeout' => 20));
											*/
										}

Commented out the segment above, first line of the excerpt is number 89.

stripe-cancellation.inc.php

	public static function stripe_cancellation()
	{
		/* Disabled the Function Below
		if(!empty($_POST['s2member_pro_stripe_cancellation']))
			c_ws_plugin__s2member_pro_stripe_cancellation_in::stripe_cancellation();
		*/
	}

I added the return false and I commented out the original. Not sure what this does but hopefully it cripples one item necessary.

stripe-utilities.inc.php

		try // Attempt to cancel the subscription for this customer.
		{
			/* Deactivated Routines Below
			// Check for draft/open invoice and void.
			$subscription = \Stripe\Subscription::retrieve($subscription_id);
			if (!empty($subscription->latest_invoice)) {
				$latest_invoice = \Stripe\Invoice::retrieve($subscription->latest_invoice);
				// If draft, finalize to change status to "open".
				if ($latest_invoice->status == 'draft') {
					$latest_invoice = $latest_invoice->finalizeInvoice([
						'auto_advance' => false
					]);
				}
				if ($latest_invoice->status == 'open') {
					$latest_invoice = $latest_invoice->voidInvoice();
				}
			}

			// Delete subscription if cancel now, update if at period end.
			if ($cancel_at_period_end) {
				$subscription = \Stripe\Subscription::update(
					$subscription_id, 
					array('cancel_at_period_end' => true)
				);
			} else {
				$subscription = \Stripe\Subscription::retrieve($subscription_id);
				$subscription = $subscription->delete();
			}

			self::log_entry(__FUNCTION__, $input_time, $input_vars, time(), $subscription);

			return $subscription; // Stripe subscription object.
			*/
		}

Again, commented out that segment to disable it.

I am pretty sure what I am doing is extremely inelegant and might not work. Hopefully it won’t cause issues. Maybe @clavaque gives some feedback and tells me the same could be done with half line of code :crazy_face:

I’ll keep you all posted.

:slightly_smiling_face:

Just in case I did the same to paypal-cancellation.inc.php

if (!class_exists ("c_ws_plugin__s2member_pro_paypal_cancellation"))
	{
		/**
		* PayPal Cancellation Form processing.
		*
		* @package s2Member\PayPal
		* @since 1.5
		*/
		class c_ws_plugin__s2member_pro_paypal_cancellation
			{
				/**
				* Handles processing of Pro-Form cancellations.
				*
				* @package s2Member\PayPal
				* @since 1.5
				*
				* @attaches-to ``add_action("init");``
				*
				* @return null|inner Return-value of inner routine.
				*/
				public static function paypal_cancellation ()
					{
						if (!empty($_POST["s2member_pro_paypal_cancellation"]))
							{
								/* Disabled Routine Below to Prevent Cancellations
								if($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_payflow_api_username"])
									return c_ws_plugin__s2member_pro_paypal_cancellation_pf_in::paypal_cancellation();

								return c_ws_plugin__s2member_pro_paypal_cancellation_in::paypal_cancellation ();
								*/
							}
					}
			}
	}

You can see the part I commented out near the end.

Also edited paypal-utilities.inc.php

		/**
		 * Cancels a Payflow recurring profile.
		 *
		 * @package s2Member\PayPal
		 * @since 110531
		 *
		 * @param string $subscr_id A paid subscription ID (aka: Recurring Profile ID).
		 * @param string $baid A Billing Agreement ID (aka: BAID).
		 *
		 * @return boolean True if the profile was cancelled, else false.
		 */
		public static function payflow_cancel_profile($subscr_id = '', $baid = '')
		{
			/* Disabled Routine Below to Prevent Cancellations
			
			$payflow['TRXTYPE']       = 'R';
			$payflow['ACTION']        = 'C';
			$payflow['TENDER']        = 'C';
			$payflow['ORIGPROFILEID'] = $subscr_id;

			if(($cancellation = c_ws_plugin__s2member_paypal_utilities::paypal_payflow_api_response($payflow)) && empty($cancellation['__error']))
				if(!$baid || c_ws_plugin__s2member_pro_paypal_utilities::payflow_cancel_billing_agreement($baid))
					return TRUE;

			$payflow['TENDER'] = 'P';
			if(($cancellation = c_ws_plugin__s2member_paypal_utilities::paypal_payflow_api_response($payflow)) && empty($cancellation['__error']))
				if(!$baid || c_ws_plugin__s2member_pro_paypal_utilities::payflow_cancel_billing_agreement($baid))
					return TRUE;
			*/

			return FALSE;
		}

		/**
		 * Cancels a Payflow Billing Agreement.
		 *
		 * @package s2Member\PayPal
		 * @since 130510
		 *
		 * @param string $baid A Billing Agreement ID (aka: BAID).
		 *
		 * @return boolean True if the agreement was cancelled, else false.
		 */
		public static function payflow_cancel_billing_agreement($baid = '')
		{
			/* Disabled Routine Below to Prevent Cancellations
			
			$payflow['ACTION']    = 'U';
			$payflow['TENDER']    = 'P';
			$payflow['BAID']      = $baid;
			$payflow['BA_STATUS'] = 'cancel';

			if(($cancellation = c_ws_plugin__s2member_paypal_utilities::paypal_payflow_api_response($payflow)) && empty($cancellation['__error']))
				return TRUE;
			*/

			return FALSE;
		}

Those are just segments of the files, not their entirety! Make any modifications at your own risk!

I attached a zip with the three modified files.stripe.zip (15.5 KB)

Stay tuned for news! :slightly_smiling_face: