mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Do not rely on existing payment tokens after purchase but on webhooks
This commit is contained in:
parent
ba7bea6fa6
commit
f03f3e5fb1
3 changed files with 0 additions and 172 deletions
|
@ -10,7 +10,6 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\Vaulting;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
|
||||
|
@ -122,42 +121,6 @@ class PaymentTokenRepository {
|
|||
return $this->token_contains_source( $tokens, 'paypal' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if tokens has the given payment source.
|
||||
*
|
||||
* @param PaymentToken[] $tokens The tokens.
|
||||
* @param PaymentSource|null $payment_source The payment source.
|
||||
* @return bool Whether tokens contains payment source or not.
|
||||
*/
|
||||
public function tokens_contains_payment_source( array $tokens, ?PaymentSource $payment_source ): bool {
|
||||
|
||||
if ( null === $payment_source ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->tokens_contains_card( $tokens ) ) {
|
||||
|
||||
$card = $payment_source->card();
|
||||
if ( null === $card ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$last_digits = $card->last_digits();
|
||||
$brand = $card->brand();
|
||||
|
||||
foreach ( $tokens as $token ) {
|
||||
if (
|
||||
$last_digits && $last_digits === $token->source()->card->last_digits
|
||||
&& $brand && $brand === $token->source()->card->brand
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch PaymentToken from PayPal for a user.
|
||||
*
|
||||
|
|
|
@ -10,8 +10,6 @@ declare( strict_types=1 );
|
|||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
use Exception;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
@ -173,100 +171,6 @@ trait ProcessPaymentTrait {
|
|||
|
||||
try {
|
||||
if ( $this->order_processor->process( $wc_order ) ) {
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->logger->info( "Checking if payment for subscription parent order #{$order_id} is saved." );
|
||||
|
||||
$tokens = $this->payment_token_repository->all_for_user_id( $wc_order->get_customer_id() );
|
||||
$current_payment_source = $this->session_handler->order()->payment_source();
|
||||
if ( $tokens && $this->payment_token_repository->tokens_contains_payment_source( $tokens, $current_payment_source ) ) {
|
||||
|
||||
$this->logger->info( "Payment for subscription parent order #{$order_id} was saved correctly." );
|
||||
|
||||
if ( $this->config->has( 'intent' ) && strtoupper( (string) $this->config->get( 'intent' ) ) === 'CAPTURE' ) {
|
||||
$this->authorized_payments_processor->capture_authorized_payment( $wc_order );
|
||||
}
|
||||
|
||||
$this->session_handler->destroy_session_data();
|
||||
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => $this->get_return_url( $wc_order ),
|
||||
);
|
||||
}
|
||||
|
||||
$this->logger->error( "Payment for subscription parent order #{$order_id} was not saved." );
|
||||
|
||||
$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.' );
|
||||
}
|
||||
$order = $this->order_endpoint->order( $paypal_order_id );
|
||||
|
||||
$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.' );
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf(
|
||||
'Trying to void order %1$s, payments: %2$s.',
|
||||
$order->id(),
|
||||
wp_json_encode( $payments->to_array() )
|
||||
)
|
||||
);
|
||||
|
||||
$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 );
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf(
|
||||
'Order %1$s voided successfully.',
|
||||
$order->id()
|
||||
)
|
||||
);
|
||||
|
||||
$error_message = __( 'Could not process order because it was not possible to save the payment.', 'woocommerce-paypal-payments' );
|
||||
$wc_order->update_status( 'failed', $error_message );
|
||||
|
||||
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
|
||||
foreach ( $subscriptions as $key => $subscription ) {
|
||||
if ( $subscription->get_parent_id() === $order_id ) {
|
||||
try {
|
||||
$subscription->update_status( 'cancelled' );
|
||||
break;
|
||||
} catch ( Exception $exception ) {
|
||||
$this->logger->error( "Could not update cancelled status on subscription #{$subscription->get_id()} " . $exception->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adds retry counter meta to avoid duplicate invoice id error on consequent tries.
|
||||
$wc_order->update_meta_data( 'ppcp-retry', (int) $wc_order->get_meta( 'ppcp-retry' ) + 1 );
|
||||
$wc_order->save_meta_data();
|
||||
|
||||
$this->session_handler->destroy_session_data();
|
||||
wc_add_notice( $error_message, 'error' );
|
||||
|
||||
return $failure_data;
|
||||
}
|
||||
|
||||
WC()->cart->empty_cart();
|
||||
$this->session_handler->destroy_session_data();
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace PHPUnit\Vaulting;
|
||||
|
||||
use Mockery;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentSource;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentTokenFactory;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
||||
|
||||
class PaymentTokenRepositoryTest extends TestCase
|
||||
{
|
||||
|
||||
public function testTokensContainsCardPaymentSource()
|
||||
{
|
||||
$paymentSource = Mockery::mock(PaymentSource::class);
|
||||
$paymentSource->shouldReceive('card->last_digits')->andReturn('1234');
|
||||
$paymentSource->shouldReceive('card->brand')->andReturn('VISA');
|
||||
|
||||
$token = Mockery::mock(PaymentToken::class);
|
||||
$source = (object)[
|
||||
'card' => (object)[
|
||||
'last_digits' => '1234',
|
||||
'brand' => 'VISA',
|
||||
],
|
||||
];
|
||||
|
||||
$token->shouldReceive('source')->andReturn($source);
|
||||
$tokens = [$token];
|
||||
|
||||
$factory = Mockery::mock(PaymentTokenFactory::class);
|
||||
$endpoint = Mockery::mock(PaymentTokenEndpoint::class);
|
||||
$testee = new PaymentTokenRepository($factory, $endpoint);
|
||||
|
||||
self::assertTrue($testee->tokens_contains_payment_source($tokens, $paymentSource));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue