Merge pull request #708 from woocommerce/PCP-581-capture-virtual-only-orders-problem-for-subscriptions

Capture virtual renewal orders functionality for subscription products
This commit is contained in:
Alex Pantechovskis 2022-07-26 16:22:00 +03:00 committed by GitHub
commit 5a1c65d3e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 17 deletions

View file

@ -24,6 +24,8 @@ return array(
$purchase_unit_factory = $container->get( 'api.factory.purchase-unit' );
$payer_factory = $container->get( 'api.factory.payer' );
$environment = $container->get( 'onboarding.environment' );
$settings = $container->get( 'wcgateway.settings' );
$authorized_payments_processor = $container->get( 'wcgateway.processor.authorized-payments' );
return new RenewalHandler(
$logger,
$repository,
@ -31,7 +33,9 @@ return array(
$purchase_unit_factory,
$container->get( 'api.factory.shipping-preference' ),
$payer_factory,
$environment
$environment,
$settings,
$authorized_payments_processor
);
},
'subscription.repository.payment-token' => static function ( ContainerInterface $container ): PaymentTokenRepository {

View file

@ -10,6 +10,7 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Subscription;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
@ -17,10 +18,12 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
/**
* Class RenewalHandler
@ -80,16 +83,32 @@ class RenewalHandler {
*/
protected $environment;
/**
* The settings
*
* @var Settings
*/
protected $settings;
/**
* The processor for authorized payments.
*
* @var AuthorizedPaymentsProcessor
*/
protected $authorized_payments_processor;
/**
* RenewalHandler constructor.
*
* @param LoggerInterface $logger The logger.
* @param PaymentTokenRepository $repository The payment token repository.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param PayerFactory $payer_factory The payer factory.
* @param Environment $environment The environment.
* @param LoggerInterface $logger The logger.
* @param PaymentTokenRepository $repository The payment token repository.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping_preference factory.
* @param PayerFactory $payer_factory The payer factory.
* @param Environment $environment The environment.
* @param Settings $settings The Settings.
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The Authorized Payments Processor.
*/
public function __construct(
LoggerInterface $logger,
@ -98,16 +117,20 @@ class RenewalHandler {
PurchaseUnitFactory $purchase_unit_factory,
ShippingPreferenceFactory $shipping_preference_factory,
PayerFactory $payer_factory,
Environment $environment
Environment $environment,
Settings $settings,
AuthorizedPaymentsProcessor $authorized_payments_processor
) {
$this->logger = $logger;
$this->repository = $repository;
$this->order_endpoint = $order_endpoint;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->payer_factory = $payer_factory;
$this->environment = $environment;
$this->logger = $logger;
$this->repository = $repository;
$this->order_endpoint = $order_endpoint;
$this->purchase_unit_factory = $purchase_unit_factory;
$this->shipping_preference_factory = $shipping_preference_factory;
$this->payer_factory = $payer_factory;
$this->environment = $environment;
$this->settings = $settings;
$this->authorized_payments_processor = $authorized_payments_processor;
}
/**
@ -179,6 +202,14 @@ class RenewalHandler {
}
$this->handle_new_order_status( $order, $wc_order );
if ( $this->capture_authorized_downloads( $order ) && AuthorizedPaymentsProcessor::SUCCESSFUL === $this->authorized_payments_processor->process( $wc_order ) ) {
$wc_order->add_order_note(
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
);
$wc_order->update_meta_data( AuthorizedPaymentsProcessor::CAPTURED_META_KEY, 'true' );
$wc_order->update_status( 'completed' );
}
}
/**
@ -229,4 +260,39 @@ class RenewalHandler {
return current( $tokens );
}
/**
* Returns if an order should be captured immediately.
*
* @param Order $order The PayPal order.
*
* @return bool
* @throws NotFoundException When a setting was not found.
*/
protected function capture_authorized_downloads( Order $order ): bool {
if (
! $this->settings->has( 'capture_for_virtual_only' )
|| ! $this->settings->get( 'capture_for_virtual_only' )
) {
return false;
}
if ( $order->intent() === 'CAPTURE' ) {
return false;
}
/**
* We fetch the order again as the authorize endpoint (from which the Order derives)
* drops the item's category, making it impossible to check, if purchase units contain
* physical goods.
*/
$order = $this->order_endpoint->order( $order->id() );
foreach ( $order->purchase_units() as $unit ) {
if ( $unit->contains_physical_goods() ) {
return false;
}
}
return true;
}
}