diff --git a/modules/ppcp-wc-subscriptions/services.php b/modules/ppcp-wc-subscriptions/services.php index bfd6eb148..be3bb7f04 100644 --- a/modules/ppcp-wc-subscriptions/services.php +++ b/modules/ppcp-wc-subscriptions/services.php @@ -39,7 +39,8 @@ return array( $settings, $authorized_payments_processor, $funding_source_renderer, - $container->get( 'save-payment-methods.helpers.real-time-account-updater' ) + $container->get( 'save-payment-methods.helpers.real-time-account-updater' ), + $container->get( 'wc-subscriptions.helper' ) ); }, 'wc-subscriptions.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository { diff --git a/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php b/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php index 3ece94804..c0247c3a1 100644 --- a/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php +++ b/modules/ppcp-wc-subscriptions/src/Helper/SubscriptionHelper.php @@ -13,6 +13,7 @@ namespace WooCommerce\PayPalCommerce\WcSubscriptions\Helper; use WC_Product; use WC_Product_Subscription_Variation; +use WC_Subscription; use WC_Subscriptions; use WC_Subscriptions_Product; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; @@ -299,4 +300,35 @@ class SubscriptionHelper { 'cart' => $this->cart_contains_subscription(), ); } + + /** + * Returns previous order transaction from the given subscription. + * + * @param WC_Subscription $subscription WooCommerce Subscription. + * @return string + */ + public function previous_transaction( WC_Subscription $subscription ): string { + $orders = $subscription->get_related_orders( 'all', array( 'parent', 'renewal' ) ); + if ( ! $orders ) { + return ''; + } + + // Sort orders by key descending. + krsort( $orders ); + + // Removes first order (the current processing order). + unset( $orders[ array_key_first( $orders ) ] ); + + foreach ( $orders as $order_id ) { + $order = wc_get_order( $order_id ); + if ( in_array( $order->get_status(), array( 'processing', 'completed' ), true ) ) { + $transaction_id = $order->get_transaction_id() ?? ''; + if ( $transaction_id ) { + return $transaction_id; + } + } + } + + return ''; + } } diff --git a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php index d5c85f3bf..f631184fd 100644 --- a/modules/ppcp-wc-subscriptions/src/RenewalHandler.php +++ b/modules/ppcp-wc-subscriptions/src/RenewalHandler.php @@ -37,6 +37,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait; use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait; use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait; use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings; +use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper; /** * Class RenewalHandler @@ -124,6 +125,13 @@ class RenewalHandler { */ private $real_time_account_updater_helper; + /** + * Subscription helper. + * + * @var SubscriptionHelper + */ + private $subscription_helper; + /** * RenewalHandler constructor. * @@ -138,6 +146,7 @@ class RenewalHandler { * @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor. * @param FundingSourceRenderer $funding_source_renderer The funding source renderer. * @param RealTimeAccountUpdaterHelper $real_time_account_updater_helper Real Time Account Updater helper. + * @param SubscriptionHelper $subscription_helper Subscription helper. */ public function __construct( LoggerInterface $logger, @@ -150,7 +159,8 @@ class RenewalHandler { Settings $settings, AuthorizedPaymentsProcessor $authorized_payments_processor, FundingSourceRenderer $funding_source_renderer, - RealTimeAccountUpdaterHelper $real_time_account_updater_helper + RealTimeAccountUpdaterHelper $real_time_account_updater_helper, + SubscriptionHelper $subscription_helper ) { $this->logger = $logger; @@ -164,6 +174,7 @@ class RenewalHandler { $this->authorized_payments_processor = $authorized_payments_processor; $this->funding_source_renderer = $funding_source_renderer; $this->real_time_account_updater_helper = $real_time_account_updater_helper; + $this->subscription_helper = $subscription_helper; } /** @@ -451,12 +462,6 @@ class RenewalHandler { if ( $payment_source instanceof PaymentSource ) { $this->update_payment_source( $payment_source, $wc_order ); } - - $subscriptions = wcs_get_subscriptions_for_order( $wc_order->get_id(), array( 'order_type' => 'any' ) ); - foreach ( $subscriptions as $id => $subscription ) { - $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); - $subscription->save(); - } } $this->handle_new_order_status( $order, $wc_order ); @@ -479,19 +484,17 @@ class RenewalHandler { 'vault_id' => $token, ); - $stored_credentials = array( - 'payment_initiator' => 'MERCHANT', - 'payment_type' => 'RECURRING', - 'usage' => 'SUBSEQUENT', - ); - $subscriptions = wcs_get_subscriptions_for_renewal_order( $wc_order ); - foreach ( $subscriptions as $post_id => $subscription ) { - $previous_transaction_reference = $subscription->get_meta( 'ppcp_previous_transaction_reference' ); - if ( $previous_transaction_reference ) { - $stored_credentials['previous_transaction_reference'] = $previous_transaction_reference; - $properties['stored_credentials'] = $stored_credentials; - break; + $subscription = end( $subscriptions ); + if ( $subscription ) { + $transaction = $this->subscription_helper->previous_transaction( $subscription ); + if ( $transaction ) { + $properties['stored_credentials'] = array( + 'payment_initiator' => 'MERCHANT', + 'payment_type' => 'RECURRING', + 'usage' => 'SUBSEQUENT', + 'previous_transaction_reference' => $transaction, + ); } } diff --git a/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php b/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php index 861ca55c1..9d19dc0ac 100644 --- a/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php +++ b/modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php @@ -104,14 +104,6 @@ class WcSubscriptionsModule implements ModuleInterface { if ( count( $subscription->get_related_orders() ) === 1 ) { $parent_order = $subscription->get_parent(); if ( is_a( $parent_order, WC_Order::class ) ) { - $order_repository = $c->get( 'api.repository.order' ); - $order = $order_repository->for_wc_order( $parent_order ); - $transaction_id = $this->get_paypal_order_transaction_id( $order ); - if ( $transaction_id ) { - $subscription->update_meta_data( 'ppcp_previous_transaction_reference', $transaction_id ); - $subscription->save(); - } - // Update the initial payment method title if not the same as the first order. $payment_method_title = $parent_order->get_payment_method_title(); if (