Skip to content

Commit 6a91f17

Browse files
authored
Dynamically fetch OAuth URLs when needed (#3841)
* Dynamically fetch OAuth URLs when needed This prevents always loading OAuth URLs at page load and then loading them via AJAX when needed. - Add checks to prevent OAuth URL calls at page loads. - Add AJAX endpoint to fetch Stripe OAuth URLs dynamically - Update client-side React component to load OAuth URLs asynchronously - Conditionally fetch OAuth URLs based on account connection status * Add a test * Add changelog entries * Move loading indicator into the primary button
1 parent 674e579 commit 6a91f17

File tree

5 files changed

+147
-41
lines changed

5 files changed

+147
-41
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* Fix - Improve the appearance of Stripe elements in checkout pages to match the store theme.
4242
* Fix - Hide ECE button for synced subscription variations.
4343
* Fix - Use the original shipping address for Amazon Pay pay for orders.
44+
* Tweak - Improve settings page load by delaying oauth URL generation.
4445
* Tweak - Update the Woo logo in the Configure connection modal
4546

4647
= 9.1.1 - 2025-01-10 =

client/settings/stripe-auth-account/stripe-auth-actions.js

Lines changed: 75 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
/* global wc_stripe_settings_params */
1+
/* global wc_stripe_settings_params, ajaxurl */
22
import { __ } from '@wordpress/i18n';
3-
import { React } from 'react';
3+
import { React, useState, useEffect } from 'react';
44
import { Button, ExternalLink } from '@wordpress/components';
55
import interpolateComponents from 'interpolate-components';
66
import ConfigureWebhookButton from './configure-webhook-button';
@@ -16,46 +16,86 @@ import InlineNotice from 'wcstripe/components/inline-notice';
1616
* @return {JSX.Element} The rendered StripeAuthActions component.
1717
*/
1818
const StripeAuthActions = ( { testMode, displayWebhookConfigure } ) => {
19-
const oauthUrl = testMode // eslint-disable-next-line camelcase
20-
? wc_stripe_settings_params.stripe_test_oauth_url // eslint-disable-next-line camelcase
21-
: wc_stripe_settings_params.stripe_oauth_url;
19+
const [ oauthUrls, setOauthUrls ] = useState( {
20+
oauth_url: '',
21+
test_oauth_url: '',
22+
} );
23+
const [ isLoading, setIsLoading ] = useState( true );
24+
const [ error, setError ] = useState( null );
2225

23-
return oauthUrl ? (
24-
<div className="woocommerce-stripe-auth__actions">
25-
<Button
26-
variant="primary"
27-
href={ oauthUrl }
28-
text={
29-
testMode
30-
? __(
31-
'Create or connect a test account',
32-
'woocommerce-gateway-stripe'
33-
)
34-
: __(
35-
'Create or connect an account',
26+
useEffect( () => {
27+
const fetchOAuthUrls = async () => {
28+
try {
29+
const response = await jQuery.ajax( {
30+
url: ajaxurl,
31+
method: 'POST',
32+
data: {
33+
action: 'wc_stripe_get_oauth_urls',
34+
nonce: wc_stripe_settings_params.oauth_nonce, // eslint-disable-line camelcase
35+
},
36+
} );
37+
38+
if ( response.success ) {
39+
setOauthUrls( response.data );
40+
} else {
41+
setError(
42+
response.data?.message ||
43+
__(
44+
'Failed to fetch OAuth URLs',
3645
'woocommerce-gateway-stripe'
37-
)
46+
)
47+
);
3848
}
39-
/>
49+
} catch ( err ) {
50+
setError(
51+
__(
52+
'Failed to fetch OAuth URLs',
53+
'woocommerce-gateway-stripe'
54+
)
55+
);
56+
} finally {
57+
setIsLoading( false );
58+
}
59+
};
60+
61+
fetchOAuthUrls();
62+
}, [] );
63+
64+
const oauthUrl = testMode ? oauthUrls.test_oauth_url : oauthUrls.oauth_url;
65+
const buttonText = testMode
66+
? __( 'Create or connect a test account', 'woocommerce-gateway-stripe' )
67+
: __( 'Create or connect an account', 'woocommerce-gateway-stripe' );
68+
69+
return (
70+
<div className="woocommerce-stripe-auth__actions">
71+
{ error ? (
72+
<InlineNotice isDismissible={ false } status="error">
73+
{ interpolateComponents( {
74+
mixedString: __(
75+
'An issue occurred generating a connection to Stripe, please ensure your server has a valid SSL certificate and try again.{{br /}}For assistance, refer to our {{Link}}documentation{{/Link}}.',
76+
'woocommerce-gateway-stripe'
77+
),
78+
components: {
79+
br: <br />,
80+
Link: (
81+
<ExternalLink href="https://woocommerce.com/document/stripe/setup-and-configuration/connecting-to-stripe/" />
82+
),
83+
},
84+
} ) }
85+
</InlineNotice>
86+
) : (
87+
<Button
88+
variant="primary"
89+
href={ oauthUrl }
90+
text={ buttonText }
91+
disabled={ isLoading }
92+
isBusy={ isLoading }
93+
/>
94+
) }
4095
{ displayWebhookConfigure && (
4196
<ConfigureWebhookButton testMode={ testMode } />
4297
) }
4398
</div>
44-
) : (
45-
<InlineNotice isDismissible={ false } status="error">
46-
{ interpolateComponents( {
47-
mixedString: __(
48-
'An issue occurred generating a connection to Stripe, please ensure your server has a valid SSL certificate and try again.{{br /}}For assistance, refer to our {{Link}}documentation{{/Link}}.',
49-
'woocommerce-gateway-stripe'
50-
),
51-
components: {
52-
br: <br />,
53-
Link: (
54-
<ExternalLink href="https://woocommerce.com/document/stripe/setup-and-configuration/connecting-to-stripe/" />
55-
),
56-
},
57-
} ) }
58-
</InlineNotice>
5999
);
60100
};
61101

includes/admin/class-wc-stripe-settings-controller.php

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public function __construct( WC_Stripe_Account $account, ?WC_Stripe_Payment_Gate
4444
add_action( 'admin_init', [ $this, 'maybe_update_account_data' ] );
4545

4646
add_action( 'update_option_woocommerce_gateway_order', [ $this, 'set_stripe_gateways_in_list' ] );
47+
48+
// Add AJAX handler for OAuth URLs
49+
add_action( 'wp_ajax_wc_stripe_get_oauth_urls', [ $this, 'ajax_get_oauth_urls' ] );
4750
}
4851

4952
/**
@@ -115,6 +118,53 @@ public function admin_options( WC_Stripe_Payment_Gateway $gateway ) {
115118
echo $account_data_exists ? '<div id="wc-stripe-account-settings-container"></div>' : '<div id="wc-stripe-new-account-container"></div>';
116119
}
117120

121+
/**
122+
* AJAX handler to get OAuth URLs for the configuration modal
123+
*/
124+
public function ajax_get_oauth_urls() {
125+
// Check nonce and capabilities
126+
if ( ! check_ajax_referer( 'wc_stripe_get_oauth_urls', 'nonce', false ) ||
127+
! current_user_can( 'manage_woocommerce' ) ) {
128+
wp_send_json_error( [ 'message' => __( 'You do not have permission to do this.', 'woocommerce-gateway-stripe' ) ] );
129+
return;
130+
}
131+
132+
$oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url();
133+
$test_oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url( '', 'test' );
134+
135+
wp_send_json_success(
136+
[
137+
'oauth_url' => is_wp_error( $oauth_url ) ? '' : $oauth_url,
138+
'test_oauth_url' => is_wp_error( $test_oauth_url ) ? '' : $test_oauth_url,
139+
]
140+
);
141+
}
142+
143+
/**
144+
* Determines if OAuth URLs need to be generated.
145+
* URLs are needed for new accounts or accounts not connected via OAuth.
146+
*
147+
* @return bool True if OAuth URLs are needed
148+
*/
149+
public function needs_oauth_urls() {
150+
$settings = WC_Stripe_Helper::get_stripe_settings();
151+
$has_live_keys = ! empty( $settings['publishable_key'] ) && ! empty( $settings['secret_key'] );
152+
$has_test_keys = ! empty( $settings['test_publishable_key'] ) && ! empty( $settings['test_secret_key'] );
153+
154+
// If no keys at all, we need OAuth URLs for new account setup
155+
if ( ! $has_live_keys && ! $has_test_keys ) {
156+
return true;
157+
}
158+
159+
$stripe_connect = woocommerce_gateway_stripe()->connect;
160+
161+
// Check each mode only if it has keys
162+
$needs_live_oauth = $has_live_keys && ! $stripe_connect->is_connected_via_oauth( 'live' );
163+
$needs_test_oauth = $has_test_keys && ! $stripe_connect->is_connected_via_oauth( 'test' );
164+
165+
return $needs_live_oauth || $needs_test_oauth;
166+
}
167+
118168
/**
119169
* Load admin scripts.
120170
*/
@@ -139,8 +189,6 @@ public function admin_scripts( $hook_suffix ) {
139189
return;
140190
}
141191

142-
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
143-
144192
// Webpack generates an assets file containing a dependencies array for our built JS file.
145193
$script_asset_path = WC_STRIPE_PLUGIN_PATH . '/build/upe_settings.asset.php';
146194
$script_asset = file_exists( $script_asset_path )
@@ -164,11 +212,17 @@ public function admin_scripts( $hook_suffix ) {
164212
$script_asset['version']
165213
);
166214

167-
$oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url();
168-
$oauth_url = is_wp_error( $oauth_url ) ? '' : $oauth_url;
215+
$oauth_url = '';
216+
$test_oauth_url = '';
169217

170-
$test_oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url( '', 'test' );
171-
$test_oauth_url = is_wp_error( $test_oauth_url ) ? '' : $test_oauth_url;
218+
// Get URLs at page load only if account doesn't exist or if account exists but not connected via OAuth
219+
if ( $this->needs_oauth_urls() ) {
220+
$oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url();
221+
$oauth_url = is_wp_error( $oauth_url ) ? '' : $oauth_url;
222+
223+
$test_oauth_url = woocommerce_gateway_stripe()->connect->get_oauth_url( '', 'test' );
224+
$test_oauth_url = is_wp_error( $test_oauth_url ) ? '' : $test_oauth_url;
225+
}
172226

173227
$message = sprintf(
174228
/* translators: 1) Html strong opening tag 2) Html strong closing tag */
@@ -193,6 +247,7 @@ public function admin_scripts( $hook_suffix ) {
193247
'are_apms_deprecated' => WC_Stripe_Feature_Flags::are_apms_deprecated(),
194248
'is_ece_enabled' => WC_Stripe_Feature_Flags::is_stripe_ece_enabled(),
195249
'is_amazon_pay_available' => WC_Stripe_Feature_Flags::is_amazon_pay_available(),
250+
'oauth_nonce' => wp_create_nonce( 'wc_stripe_get_oauth_urls' ),
196251
];
197252
wp_localize_script(
198253
'woocommerce_stripe_admin',

readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
151151
* Fix - Improve the appearance of Stripe elements in checkout pages to match the store theme.
152152
* Fix - Hide ECE button for synced subscription variations.
153153
* Fix - Use the original shipping address for Amazon Pay pay for orders.
154+
* Tweak - Improve settings page load by delaying oauth URL generation.
154155
* Tweak - Update the Woo logo in the Configure connection modal
155156

156157
[See changelog for all versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt).

tests/phpunit/admin/test-class-wc-stripe-settings-controller.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,13 @@ public function test_add_buttons_action_is_called_on_order_admin_page() {
109109
$output = ob_get_clean();
110110
$this->assertStringMatchesFormat( '%aclass="button button-disabled"%a', $output );
111111
}
112+
113+
/**
114+
* Test that needs_oauth_urls returns true for new accounts with no keys
115+
*/
116+
public function test_needs_oauth_urls_new_account() {
117+
WC_Stripe_Helper::delete_main_stripe_settings();
118+
119+
$this->assertTrue( $this->controller->needs_oauth_urls() );
120+
}
112121
}

0 commit comments

Comments
 (0)