Skip to content

Commit e7ab0c0

Browse files
authored
Merge pull request #3741 from woocommerce/PCP-5408-fix-3-2-0-release-issues
Fix 3.2.0 release issues (5408)
2 parents be1db01 + 10a8d6a commit e7ab0c0

File tree

8 files changed

+157
-97
lines changed

8 files changed

+157
-97
lines changed

modules/ppcp-api-client/src/Endpoint/PaymentTokenEndpoint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* The payment token endpoint.
3+
* Payment tokens for vault version 2 endpoint.
44
*
55
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
66
*/

modules/ppcp-api-client/src/Endpoint/PaymentTokensEndpoint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22
/**
3-
* Payment tokens version 3 endpoint.
3+
* Payment tokens for vault version 3 endpoint.
44
*
55
* @package WooCommerce\PayPalCommerce\ApiClient\Endpoint
66
*/

modules/ppcp-button/resources/js/modules/ContextBootstrap/MessagesBootstrap.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class MessagesBootstrap {
105105
setVisible( renderer.config.wrapper, shouldShow );
106106
renderer.renderWithAmount( this.lastAmount );
107107
} )
108-
.catch( ( err ) => console.error( err ) );
108+
.catch( () => {} ); // Element not found, this is expected for certain contexts.
109109
} );
110110
}
111111
}

modules/ppcp-save-payment-methods/resources/js/add-payment-method.js

Lines changed: 76 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ORDER_BUTTON_SELECTOR,
44
PaymentMethods,
55
} from '../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState';
6-
import { loadScript } from '@paypal/paypal-js';
6+
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
77
import ErrorHandler from '../../../ppcp-button/resources/js/modules/ErrorHandler';
88
import { buttonConfiguration, cardFieldsConfiguration } from './Configuration';
99
import { renderFields } from '../../../ppcp-card-fields/resources/js/Render';
@@ -13,7 +13,7 @@ import {
1313
} from '../../../ppcp-button/resources/js/modules/Helper/Hiding';
1414

1515
( function ( { ppcp_add_payment_method, jQuery } ) {
16-
document.addEventListener( 'DOMContentLoaded', () => {
16+
document.addEventListener( 'DOMContentLoaded', async () => {
1717
jQuery( document.body ).on(
1818
'click init_add_payment_method',
1919
'.payment_methods input.input-radio',
@@ -41,69 +41,88 @@ import {
4141
}
4242
}
4343

44-
setTimeout( () => {
45-
loadScript( {
46-
clientId: ppcp_add_payment_method.client_id,
47-
merchantId: ppcp_add_payment_method.merchant_id,
48-
dataUserIdToken: ppcp_add_payment_method.id_token,
49-
components: 'buttons,card-fields',
50-
} ).then( ( paypal ) => {
51-
const errorHandler = new ErrorHandler(
52-
ppcp_add_payment_method.labels.error.generic,
53-
document.querySelector( '.woocommerce-notices-wrapper' )
54-
);
55-
errorHandler.clear();
44+
const errorHandler = new ErrorHandler(
45+
ppcp_add_payment_method.labels.error.generic,
46+
document.querySelector( '.woocommerce-notices-wrapper' )
47+
);
48+
errorHandler.clear();
5649

57-
const paypalButtonContainer = document.querySelector(
58-
`#ppc-button-${ PaymentMethods.PAYPAL }-save-payment-method`
59-
);
50+
try {
51+
const config = {
52+
url_params: {
53+
'client-id': ppcp_add_payment_method.client_id,
54+
'merchant-id': ppcp_add_payment_method.merchant_id,
55+
components: 'buttons,card-fields',
56+
},
57+
save_payment_methods: {
58+
id_token: ppcp_add_payment_method.id_token,
59+
},
60+
user: {
61+
is_logged: ppcp_add_payment_method.user?.is_logged ?? false,
62+
},
63+
};
6064

61-
if ( paypalButtonContainer ) {
62-
paypal
63-
.Buttons(
64-
buttonConfiguration(
65-
ppcp_add_payment_method,
66-
errorHandler
67-
)
68-
)
69-
.render(
70-
`#ppc-button-${ PaymentMethods.PAYPAL }-save-payment-method`
71-
);
72-
}
65+
const paypal = await loadPayPalScript(
66+
'ppcp-add-payment-method',
67+
config
68+
);
69+
70+
const paypalButtonContainer = document.querySelector(
71+
`#ppc-button-${ PaymentMethods.PAYPAL }-save-payment-method`
72+
);
7373

74-
const cardFields = paypal.CardFields(
75-
cardFieldsConfiguration(
76-
ppcp_add_payment_method,
77-
errorHandler
74+
if ( paypalButtonContainer ) {
75+
paypal
76+
.Buttons(
77+
buttonConfiguration(
78+
ppcp_add_payment_method,
79+
errorHandler
80+
)
7881
)
79-
);
82+
.render(
83+
`#ppc-button-${ PaymentMethods.PAYPAL }-save-payment-method`
84+
);
85+
}
8086

81-
if ( cardFields.isEligible() ) {
82-
renderFields( cardFields );
83-
}
87+
const cardFields = paypal.CardFields(
88+
cardFieldsConfiguration(
89+
ppcp_add_payment_method,
90+
errorHandler
91+
)
92+
);
8493

85-
const placeOrderButton =
86-
document.querySelector( '#place_order' );
87-
placeOrderButton?.addEventListener( 'click', ( event ) => {
88-
const cardPaymentToken = document.querySelector(
89-
'input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked'
90-
)?.value;
91-
if (
92-
getCurrentPaymentMethod() !==
93-
'ppcp-credit-card-gateway' ||
94-
( cardPaymentToken && cardPaymentToken !== 'new' )
95-
) {
96-
return;
97-
}
98-
placeOrderButton.disabled = true;
99-
event.preventDefault();
100-
cardFields.submit().catch( ( error ) => {
101-
console.error( error );
102-
placeOrderButton.disabled = false;
103-
} );
94+
if ( cardFields.isEligible() ) {
95+
renderFields( cardFields );
96+
}
97+
98+
const placeOrderButton =
99+
document.querySelector( '#place_order' );
100+
placeOrderButton?.addEventListener( 'click', ( event ) => {
101+
const cardPaymentToken = document.querySelector(
102+
'input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked'
103+
)?.value;
104+
if (
105+
getCurrentPaymentMethod() !==
106+
'ppcp-credit-card-gateway' ||
107+
( cardPaymentToken && cardPaymentToken !== 'new' )
108+
) {
109+
return;
110+
}
111+
placeOrderButton.disabled = true;
112+
event.preventDefault();
113+
cardFields.submit().catch( ( error ) => {
114+
console.error( error );
115+
errorHandler.message( ppcp_add_payment_method.error_message );
116+
placeOrderButton.disabled = false;
104117
} );
105118
} );
106-
}, 1000 );
119+
} catch ( error ) {
120+
console.error( 'Failed to load PayPal script:', error );
121+
errorHandler.message(
122+
ppcp_add_payment_method.labels.error.generic ||
123+
'Failed to load PayPal. Please refresh the page.'
124+
);
125+
}
107126
} );
108127
} )( {
109128
ppcp_add_payment_method: window.ppcp_add_payment_method,

modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ function () use ( $c ) {
304304
'subscription_id_to_change_payment' => $is_subscription_change_payment_method_page ? (int) $change_payment_method : 0,
305305
'error_message' => __( 'Could not save payment method.', 'woocommerce-paypal-payments' ),
306306
'verification_method' => $verification_method,
307+
'user' => array(
308+
'is_logged' => is_user_logged_in(),
309+
),
307310
'ajax' => array(
308311
'create_setup_token' => array(
309312
'endpoint' => \WC_AJAX::get_endpoint( CreateSetupToken::ENDPOINT ),

modules/ppcp-save-payment-methods/src/Service/PaymentMethodTokensChecker.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Service;
1111

1212
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
13+
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
1314

1415
class PaymentMethodTokensChecker {
1516

@@ -35,12 +36,16 @@ public function has_paypal_payment_token( string $customer_id ): bool {
3536
return false;
3637
}
3738

38-
$tokens = $this->payment_method_tokens_endpoint->payment_tokens_for_customer( $customer_id );
39-
foreach ( $tokens as $token ) {
40-
$payment_source = $token['payment_source']->name() ?? '';
41-
if ( $payment_source === 'paypal' ) {
42-
return true;
39+
try {
40+
$tokens = $this->payment_method_tokens_endpoint->payment_tokens_for_customer( $customer_id );
41+
foreach ( $tokens as $token ) {
42+
$payment_source = $token['payment_source']->name() ?? '';
43+
if ( $payment_source === 'paypal' ) {
44+
return true;
45+
}
4346
}
47+
} catch ( RuntimeException $e ) {
48+
return false;
4449
}
4550

4651
return false;

modules/ppcp-vaulting/src/VaultingModule.php

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -192,46 +192,44 @@ function ( $item, $payment_token ) {
192192
add_action(
193193
'wp',
194194
function () use ( $container ) {
195-
if ( $container->get( 'vaulting.vault-v3-enabled' ) ) {
195+
global $wp;
196+
if ( ! isset( $wp->query_vars['delete-payment-method'] ) ) {
196197
return;
197198
}
198199

199-
global $wp;
200+
$token_id = absint( $wp->query_vars['delete-payment-method'] );
201+
$token = WC_Payment_Tokens::get( $token_id );
200202

201-
if ( isset( $wp->query_vars['delete-payment-method'] ) ) {
202-
$token_id = absint( $wp->query_vars['delete-payment-method'] );
203-
$token = WC_Payment_Tokens::get( $token_id );
203+
if (
204+
is_null( $token )
205+
|| ( $token->get_gateway_id() !== PayPalGateway::ID && $token->get_gateway_id() !== CreditCardGateway::ID )
206+
) {
207+
return;
208+
}
204209

205-
if (
206-
is_null( $token )
207-
|| ( $token->get_gateway_id() !== PayPalGateway::ID && $token->get_gateway_id() !== CreditCardGateway::ID )
208-
) {
209-
return;
210-
}
210+
// phpcs:ignore WordPress.Security.NonceVerification
211+
$wpnonce = wc_clean( wp_unslash( $_REQUEST['_wpnonce'] ?? '' ) );
212+
$token_id_string = (string) $token_id;
213+
$action = 'delete-payment-method-' . $token_id_string;
214+
if (
215+
$token->get_user_id() !== get_current_user_id()
216+
|| ! isset( $wpnonce ) || ! is_string( $wpnonce )
217+
|| wp_verify_nonce( $wpnonce, $action ) === false
218+
) {
219+
wc_add_notice( __( 'Invalid payment method.', 'woocommerce-paypal-payments' ), 'error' );
220+
wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) );
221+
exit();
222+
}
211223

212-
// phpcs:ignore WordPress.Security.NonceVerification
213-
$wpnonce = wc_clean( wp_unslash( $_REQUEST['_wpnonce'] ?? '' ) );
214-
$token_id_string = (string) $token_id;
215-
$action = 'delete-payment-method-' . $token_id_string;
216-
if (
217-
$token->get_user_id() !== get_current_user_id()
218-
|| ! isset( $wpnonce ) || ! is_string( $wpnonce )
219-
|| wp_verify_nonce( $wpnonce, $action ) === false
220-
) {
221-
wc_add_notice( __( 'Invalid payment method.', 'woocommerce-paypal-payments' ), 'error' );
222-
wp_safe_redirect( wc_get_account_endpoint_url( 'payment-methods' ) );
223-
exit();
224-
}
224+
try {
225+
do_action( 'woocommerce_paypal_payments_before_delete_payment_token', $token->get_token() );
225226

226-
try {
227-
do_action( 'woocommerce_paypal_payments_before_delete_payment_token', $token->get_token() );
227+
$payment_token_endpoint = $container->get( 'api.endpoint.payment-token' );
228+
$payment_token_endpoint->delete_token_by_id( $token->get_token() );
229+
} catch ( RuntimeException $exception ) {
230+
wc_add_notice( __( 'Could not delete payment token. ', 'woocommerce-paypal-payments' ) . $exception->getMessage(), 'error' );
228231

229-
$payment_token_endpoint = $container->get( 'api.endpoint.payment-token' );
230-
$payment_token_endpoint->delete_token_by_id( $token->get_token() );
231-
} catch ( RuntimeException $exception ) {
232-
wc_add_notice( __( 'Could not delete payment token. ', 'woocommerce-paypal-payments' ) . $exception->getMessage(), 'error' );
233-
return;
234-
}
232+
return;
235233
}
236234
}
237235
);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
declare( strict_types=1 );
3+
4+
namespace WooCommerce\PayPalCommerce\SavePaymentMethods\Service;
5+
6+
use Mockery;
7+
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
8+
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
9+
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
10+
use WooCommerce\PayPalCommerce\TestCase;
11+
12+
class PaymentMethodTokensCheckerTest extends TestCase {
13+
14+
public function test_handle_exception_when_resource_not_found() {
15+
$endpoint = mockery::mock( PaymentTokensEndpoint::class );
16+
$endpoint
17+
->expects( 'payment_tokens_for_customer' )
18+
->andThrow( new PayPalApiException() );
19+
20+
$checker = new PaymentMethodTokensChecker( $endpoint );
21+
22+
$this->assertFalse( $checker->has_paypal_payment_token( 'abc123' ) );
23+
}
24+
25+
public function test_handle_runtime_exception_when_network_error() {
26+
$endpoint = mockery::mock( PaymentTokensEndpoint::class );
27+
$endpoint
28+
->expects( 'payment_tokens_for_customer' )
29+
->andThrow( new RuntimeException() );
30+
31+
$checker = new PaymentMethodTokensChecker( $endpoint );
32+
33+
$this->assertFalse( $checker->has_paypal_payment_token( 'abc123' ) );
34+
}
35+
}

0 commit comments

Comments
 (0)