mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Handle free trial sub for cards
authorize 1$ and void
This commit is contained in:
parent
ade7107227
commit
f5a472673b
16 changed files with 288 additions and 69 deletions
|
@ -48,6 +48,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Repository\ApplicationContextRepository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\CustomerRepository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
|
@ -228,6 +229,11 @@ return array(
|
|||
$prefix = $container->get( 'api.prefix' );
|
||||
return new CustomerRepository( $prefix );
|
||||
},
|
||||
'api.repository.order' => static function( ContainerInterface $container ): OrderRepository {
|
||||
return new OrderRepository(
|
||||
$container->get( 'api.endpoint.order' )
|
||||
);
|
||||
},
|
||||
'api.factory.application-context' => static function ( ContainerInterface $container ) : ApplicationContextFactory {
|
||||
return new ApplicationContextFactory();
|
||||
},
|
||||
|
|
|
@ -157,6 +157,15 @@ class PurchaseUnit {
|
|||
return $this->amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the amount.
|
||||
*
|
||||
* @param Amount $amount The value to set.
|
||||
*/
|
||||
public function set_amount( Amount $amount ): void {
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shipping.
|
||||
*
|
||||
|
|
|
@ -14,12 +14,15 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\AmountBreakdown;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Item;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
|
||||
/**
|
||||
* Class AmountFactory
|
||||
*/
|
||||
class AmountFactory {
|
||||
|
||||
use FreeTrialHandlerTrait;
|
||||
|
||||
/**
|
||||
* The item factory.
|
||||
|
@ -117,9 +120,15 @@ class AmountFactory {
|
|||
* @return Amount
|
||||
*/
|
||||
public function from_wc_order( \WC_Order $order ): Amount {
|
||||
$currency = $order->get_currency();
|
||||
$items = $this->item_factory->from_wc_order( $order );
|
||||
$total = new Money( (float) $order->get_total(), $currency );
|
||||
$currency = $order->get_currency();
|
||||
$items = $this->item_factory->from_wc_order( $order );
|
||||
|
||||
$total_value = (float) $order->get_total();
|
||||
if ( CreditCardGateway::ID === $order->get_payment_method() && $this->is_free_trial_order( $order ) ) {
|
||||
$total_value = 1.0;
|
||||
}
|
||||
$total = new Money( $total_value, $currency );
|
||||
|
||||
$item_total = new Money(
|
||||
(float) array_reduce(
|
||||
$items,
|
||||
|
|
54
modules/ppcp-api-client/src/Repository/OrderRepository.php
Normal file
54
modules/ppcp-api-client/src/Repository/OrderRepository.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
/**
|
||||
* PayPal order repository.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Repository
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
/**
|
||||
* Class OrderRepository
|
||||
*/
|
||||
class OrderRepository {
|
||||
|
||||
/**
|
||||
* The order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
protected $order_endpoint;
|
||||
|
||||
/**
|
||||
* OrderRepository constructor.
|
||||
*
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
*/
|
||||
public function __construct( OrderEndpoint $order_endpoint ) {
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a PayPal order for the given WooCommerce order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return Order The PayPal order.
|
||||
* @throws RuntimeException When there is a problem getting the PayPal order.
|
||||
*/
|
||||
public function for_wc_order( WC_Order $wc_order ): Order {
|
||||
$paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
if ( ! $paypal_order_id ) {
|
||||
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
||||
}
|
||||
|
||||
return $this->order_endpoint->order( $paypal_order_id );
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import onApprove from '../OnApproveHandler/onApproveForContinue.js';
|
||||
import {payerData} from "../Helper/PayerData";
|
||||
import {PaymentMethods} from "../Helper/CheckoutMethodState";
|
||||
|
||||
class CartActionHandler {
|
||||
|
||||
|
@ -18,6 +19,7 @@ class CartActionHandler {
|
|||
body: JSON.stringify({
|
||||
nonce: this.config.ajax.create_order.nonce,
|
||||
purchase_units: [],
|
||||
payment_method: PaymentMethods.PAYPAL,
|
||||
bn_code:bnCode,
|
||||
payer,
|
||||
context:this.config.context
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import onApprove from '../OnApproveHandler/onApproveForPayNow.js';
|
||||
import {payerData} from "../Helper/PayerData";
|
||||
import {getCurrentPaymentMethod} from "../Helper/CheckoutMethodState";
|
||||
|
||||
class CheckoutActionHandler {
|
||||
|
||||
|
@ -31,6 +32,7 @@ class CheckoutActionHandler {
|
|||
bn_code:bnCode,
|
||||
context:this.config.context,
|
||||
order_id:this.config.order_id,
|
||||
payment_method: getCurrentPaymentMethod(),
|
||||
form:formValues,
|
||||
createaccount: createaccount
|
||||
})
|
||||
|
|
|
@ -2,6 +2,7 @@ import ButtonsToggleListener from '../Helper/ButtonsToggleListener';
|
|||
import Product from '../Entity/Product';
|
||||
import onApprove from '../OnApproveHandler/onApproveForContinue';
|
||||
import {payerData} from "../Helper/PayerData";
|
||||
import {PaymentMethods} from "../Helper/CheckoutMethodState";
|
||||
|
||||
class SingleProductActionHandler {
|
||||
|
||||
|
@ -84,6 +85,7 @@ class SingleProductActionHandler {
|
|||
purchase_units,
|
||||
payer,
|
||||
bn_code:bnCode,
|
||||
payment_method: PaymentMethods.PAYPAL,
|
||||
context:this.config.context
|
||||
})
|
||||
}).then(function (res) {
|
||||
|
|
|
@ -13,6 +13,9 @@ use Exception;
|
|||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Address;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\AmountBreakdown;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerName;
|
||||
|
@ -25,7 +28,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Repository\CartRepository;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -33,6 +38,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
*/
|
||||
class CreateOrderEndpoint implements EndpointInterface {
|
||||
|
||||
use FreeTrialHandlerTrait;
|
||||
|
||||
const ENDPOINT = 'ppc-create-order';
|
||||
|
||||
/**
|
||||
|
@ -177,6 +184,7 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|||
try {
|
||||
$data = $this->request_data->read_request( $this->nonce() );
|
||||
$this->parsed_request_data = $data;
|
||||
$payment_method = $data['payment_method'] ?? '';
|
||||
$wc_order = null;
|
||||
if ( 'pay-now' === $data['context'] ) {
|
||||
$wc_order = wc_get_order( (int) $data['order_id'] );
|
||||
|
@ -193,6 +201,16 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|||
$this->purchase_units = array( $this->purchase_unit_factory->from_wc_order( $wc_order ) );
|
||||
} else {
|
||||
$this->purchase_units = $this->cart_repository->all();
|
||||
|
||||
// The cart does not have any info about payment method, so we must handle free trial here.
|
||||
if ( CreditCardGateway::ID === $payment_method && $this->is_free_trial_cart() ) {
|
||||
$this->purchase_units[0]->set_amount(
|
||||
new Amount(
|
||||
new Money( 1.0, $this->purchase_units[0]->amount()->currency_code() ),
|
||||
$this->purchase_units[0]->amount()->breakdown()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->set_bn_code( $data );
|
||||
|
|
77
modules/ppcp-subscription/src/FreeTrialHandlerTrait.php
Normal file
77
modules/ppcp-subscription/src/FreeTrialHandlerTrait.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper trait for the subscriptions handling.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Subscription
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Subscription;
|
||||
|
||||
use WC_Order;
|
||||
use WC_Product;
|
||||
use WC_Subscription;
|
||||
use WC_Subscriptions_Product;
|
||||
|
||||
/**
|
||||
* Class FreeTrialHandlerTrait
|
||||
*/
|
||||
trait FreeTrialHandlerTrait {
|
||||
use SubscriptionsHandlerTrait;
|
||||
|
||||
/**
|
||||
* S.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_free_trial_cart(): bool {
|
||||
if ( ! $this->is_wcs_plugin_active() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cart = WC()->cart;
|
||||
if ( ! $cart || $cart->is_empty() || (float) $cart->get_total( 'numeric' ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $cart->get_cart() as $item ) {
|
||||
$product = $item['data'] ?? null;
|
||||
if ( ! $product instanceof WC_Product ) {
|
||||
continue;
|
||||
}
|
||||
if ( WC_Subscriptions_Product::get_trial_length( $product ) > 0 ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* S.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_free_trial_order( WC_Order $wc_order ): bool {
|
||||
if ( ! $this->is_wcs_plugin_active() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (float) $wc_order->get_total( 'numeric' ) > 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subs = wcs_get_subscriptions_for_order( $wc_order );
|
||||
|
||||
return ! empty(
|
||||
array_filter(
|
||||
$subs,
|
||||
function ( WC_Subscription $sub ): bool {
|
||||
return (float) $sub->get_total_initial_payment() <= 0;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Subscription\Helper;
|
||||
|
||||
use WC_Product;
|
||||
use WC_Subscription;
|
||||
use WC_Subscriptions_Product;
|
||||
|
||||
/**
|
||||
|
@ -46,7 +48,7 @@ class SubscriptionHelper {
|
|||
}
|
||||
|
||||
foreach ( $cart->get_cart() as $item ) {
|
||||
if ( ! isset( $item['data'] ) || ! is_a( $item['data'], \WC_Product::class ) ) {
|
||||
if ( ! isset( $item['data'] ) || ! is_a( $item['data'], WC_Product::class ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $item['data']->is_type( 'subscription' ) || $item['data']->is_type( 'subscription_variation' ) ) {
|
||||
|
|
26
modules/ppcp-subscription/src/SubscriptionsHandlerTrait.php
Normal file
26
modules/ppcp-subscription/src/SubscriptionsHandlerTrait.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper trait for the free trial subscriptions handling.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Subscription
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Subscription;
|
||||
|
||||
use WC_Subscriptions;
|
||||
|
||||
/**
|
||||
* Class SubscriptionsHandlerTrait
|
||||
*/
|
||||
trait SubscriptionsHandlerTrait {
|
||||
/**
|
||||
* Whether the subscription plugin is active or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_wcs_plugin_active(): bool {
|
||||
return class_exists( WC_Subscriptions::class );
|
||||
}
|
||||
}
|
|
@ -44,9 +44,9 @@ return array(
|
|||
'vaulting.payment-token-checker' => function( ContainerInterface $container ) : PaymentTokenChecker {
|
||||
return new PaymentTokenChecker(
|
||||
$container->get( 'vaulting.repository.payment-token' ),
|
||||
$container->get( 'api.repository.order' ),
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.processor.authorized-payments' ),
|
||||
$container->get( 'api.endpoint.order' ),
|
||||
$container->get( 'api.endpoint.payments' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
|
|
|
@ -15,8 +15,10 @@ use RuntimeException;
|
|||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\OrderRepository;
|
||||
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
@ -26,6 +28,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
*/
|
||||
class PaymentTokenChecker {
|
||||
|
||||
use FreeTrialHandlerTrait;
|
||||
|
||||
/**
|
||||
* The payment token repository.
|
||||
*
|
||||
|
@ -33,6 +37,13 @@ class PaymentTokenChecker {
|
|||
*/
|
||||
protected $payment_token_repository;
|
||||
|
||||
/**
|
||||
* The order repository.
|
||||
*
|
||||
* @var OrderRepository
|
||||
*/
|
||||
protected $order_repository;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
|
@ -47,13 +58,6 @@ class PaymentTokenChecker {
|
|||
*/
|
||||
protected $authorized_payments_processor;
|
||||
|
||||
/**
|
||||
* The order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
protected $order_endpoint;
|
||||
|
||||
/**
|
||||
* The payments endpoint.
|
||||
*
|
||||
|
@ -72,24 +76,24 @@ class PaymentTokenChecker {
|
|||
* PaymentTokenChecker constructor.
|
||||
*
|
||||
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
||||
* @param OrderRepository $order_repository The order repository.
|
||||
* @param Settings $settings The settings.
|
||||
* @param AuthorizedPaymentsProcessor $authorized_payments_processor The authorized payments processor.
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
PaymentTokenRepository $payment_token_repository,
|
||||
OrderRepository $order_repository,
|
||||
Settings $settings,
|
||||
AuthorizedPaymentsProcessor $authorized_payments_processor,
|
||||
OrderEndpoint $order_endpoint,
|
||||
PaymentsEndpoint $payments_endpoint,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->payment_token_repository = $payment_token_repository;
|
||||
$this->order_repository = $order_repository;
|
||||
$this->settings = $settings;
|
||||
$this->authorized_payments_processor = $authorized_payments_processor;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
@ -115,6 +119,16 @@ class PaymentTokenChecker {
|
|||
$tokens = $this->payment_token_repository->all_for_user_id( $customer_id );
|
||||
if ( $tokens ) {
|
||||
try {
|
||||
if ( $this->is_free_trial_order( $wc_order ) ) {
|
||||
if ( CreditCardGateway::ID === $wc_order->get_payment_method() ) {
|
||||
$order = $this->order_repository->for_wc_order( $wc_order );
|
||||
$this->authorized_payments_processor->void_authorizations( $order );
|
||||
$wc_order->payment_complete();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->capture_authorized_payment( $wc_order );
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( $exception->getMessage() );
|
||||
|
@ -126,8 +140,8 @@ class PaymentTokenChecker {
|
|||
$this->logger->error( "Payment for subscription parent order #{$order_id} was not saved on PayPal." );
|
||||
|
||||
try {
|
||||
$order = $this->get_order( $wc_order );
|
||||
$this->void_authorizations( $order );
|
||||
$order = $this->order_repository->for_wc_order( $wc_order );
|
||||
$this->authorized_payments_processor->void_authorizations( $order );
|
||||
} catch ( RuntimeException $exception ) {
|
||||
$this->logger->warning( $exception->getMessage() );
|
||||
}
|
||||
|
@ -149,55 +163,6 @@ class PaymentTokenChecker {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Voids authorizations for the given PayPal order.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @return void
|
||||
* @throws RuntimeException When there is a problem voiding authorizations.
|
||||
*/
|
||||
private function void_authorizations( Order $order ): void {
|
||||
$purchase_units = $order->purchase_units();
|
||||
if ( ! $purchase_units ) {
|
||||
throw new RuntimeException( 'No purchase units.' );
|
||||
}
|
||||
|
||||
$payments = $purchase_units[0]->payments();
|
||||
if ( ! $payments ) {
|
||||
throw new RuntimeException( 'No payments.' );
|
||||
}
|
||||
|
||||
$voidable_authorizations = array_filter(
|
||||
$payments->authorizations(),
|
||||
function ( Authorization $authorization ): bool {
|
||||
return $authorization->is_voidable();
|
||||
}
|
||||
);
|
||||
if ( ! $voidable_authorizations ) {
|
||||
throw new RuntimeException( 'No voidable authorizations.' );
|
||||
}
|
||||
|
||||
foreach ( $voidable_authorizations as $authorization ) {
|
||||
$this->payments_endpoint->void( $authorization );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a PayPal order from the given WooCommerce order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return Order The PayPal order.
|
||||
* @throws RuntimeException When there is a problem getting the PayPal order.
|
||||
*/
|
||||
private function get_order( WC_Order $wc_order ): Order {
|
||||
$paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
if ( ! $paypal_order_id ) {
|
||||
throw new RuntimeException( 'PayPal order ID not found in meta.' );
|
||||
}
|
||||
|
||||
return $this->order_endpoint->order( $paypal_order_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates WC order and subscription status to failed and canceled respectively.
|
||||
*
|
||||
|
|
|
@ -14,6 +14,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Subscription\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
|
||||
|
@ -24,7 +25,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
|||
*/
|
||||
trait ProcessPaymentTrait {
|
||||
|
||||
use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait;
|
||||
use OrderMetaTrait, PaymentsStatusHandlingTrait, TransactionIdHandlingTrait, FreeTrialHandlerTrait;
|
||||
|
||||
/**
|
||||
* Process a payment for an WooCommerce order.
|
||||
|
@ -115,7 +116,10 @@ trait ProcessPaymentTrait {
|
|||
|
||||
$this->handle_new_order_status( $order, $wc_order );
|
||||
|
||||
if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
|
||||
if ( $this->is_free_trial_order( $wc_order ) ) {
|
||||
$this->authorized_payments_processor->void_authorizations( $order );
|
||||
$wc_order->payment_complete();
|
||||
} elseif ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
|
||||
$this->authorized_payments_processor->capture_authorized_payment( $wc_order );
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
|
@ -244,6 +245,39 @@ class AuthorizedPaymentsProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Voids authorizations for the given PayPal order.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @return void
|
||||
* @throws RuntimeException When there is a problem voiding authorizations.
|
||||
*/
|
||||
public function void_authorizations( Order $order ): void {
|
||||
$purchase_units = $order->purchase_units();
|
||||
if ( ! $purchase_units ) {
|
||||
throw new RuntimeException( 'No purchase units.' );
|
||||
}
|
||||
|
||||
$payments = $purchase_units[0]->payments();
|
||||
if ( ! $payments ) {
|
||||
throw new RuntimeException( 'No payments.' );
|
||||
}
|
||||
|
||||
$voidable_authorizations = array_filter(
|
||||
$payments->authorizations(),
|
||||
function ( Authorization $authorization ): bool {
|
||||
return $authorization->is_voidable();
|
||||
}
|
||||
);
|
||||
if ( ! $voidable_authorizations ) {
|
||||
throw new RuntimeException( 'No voidable authorizations.' );
|
||||
}
|
||||
|
||||
foreach ( $voidable_authorizations as $authorization ) {
|
||||
$this->payments_endpoint->void( $authorization );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the notice for a status.
|
||||
*
|
||||
|
|
|
@ -8,6 +8,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use Mockery;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use function Brain\Monkey\Functions\expect;
|
||||
use function Brain\Monkey\Functions\when;
|
||||
|
||||
|
@ -141,6 +142,10 @@ class AmountFactoryTest extends TestCase
|
|||
->with($order)
|
||||
->andReturn([$item]);
|
||||
|
||||
$order
|
||||
->shouldReceive('get_payment_method')
|
||||
->andReturn(PayPalGateway::ID);
|
||||
|
||||
$order
|
||||
->shouldReceive('get_total')
|
||||
->andReturn(100);
|
||||
|
@ -197,6 +202,10 @@ class AmountFactoryTest extends TestCase
|
|||
->with($order)
|
||||
->andReturn([$item]);
|
||||
|
||||
$order
|
||||
->shouldReceive('get_payment_method')
|
||||
->andReturn(PayPalGateway::ID);
|
||||
|
||||
$order
|
||||
->shouldReceive('get_total')
|
||||
->andReturn(100);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue