Skip to content

Commit

Permalink
Merge branch 'develop' into update/pass-capabilities-to-onboarding-as…
Browse files Browse the repository at this point in the history
…-get-params
  • Loading branch information
mordeth authored Dec 15, 2024
2 parents 777d051 + 009bc44 commit 9801d44
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 18 deletions.
4 changes: 4 additions & 0 deletions changelog/as-fix-ece-variable-subs-free-trial
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Enable ECE for Virtual Variable Subscriptions with Free Trials.
4 changes: 4 additions & 0 deletions changelog/fix-9421-auto-enable-woopay-in-sandbox-mode
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Ensure WooPay 'enabled by default' value is correctly set in sandbox mode.
18 changes: 12 additions & 6 deletions client/connect-account-page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ const ConnectAccountPage: React.FC = () => {
}
};

const checkAccountStatus = () => {
const checkAccountStatus = ( extraQueryArgs = {} ) => {
// Fetch account status from the cache.
apiFetch( {
path: `/wc/v3/payments/accounts`,
Expand All @@ -188,18 +188,22 @@ const ConnectAccountPage: React.FC = () => {
loaderProgressRef.current > 95
) {
setTestDriveLoaderProgress( 100 );

// Redirect to the Connect URL and let it figure it out where to point the merchant.
window.location.href = addQueryArgs( connectUrl, {
const queryArgs = {
test_drive: 'true',
'wcpay-sandbox-success': 'true',
source: determineTrackingSource(),
from: 'WCPAY_CONNECT',
redirect_to_settings_page:
urlParams.get( 'redirect_to_settings_page' ) || '',
};

// Redirect to the Connect URL and let it figure it out where to point the merchant.
window.location.href = addQueryArgs( connectUrl, {
...queryArgs,
...extraQueryArgs,
} );
} else {
setTimeout( checkAccountStatus, 2000 );
setTimeout( () => checkAccountStatus( extraQueryArgs ), 2000 );
}
} );
};
Expand Down Expand Up @@ -265,7 +269,9 @@ const ConnectAccountPage: React.FC = () => {
// The account has been successfully onboarded.
if ( !! connectionSuccess ) {
// Start checking the account status in a loop.
checkAccountStatus();
checkAccountStatus( {
'wcpay-connection-success': '1',
} );
} else {
// Redirect to the response URL, but attach our test drive flags.
// This URL is generally a Connect page URL.
Expand Down
23 changes: 19 additions & 4 deletions client/express-checkout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ jQuery( ( $ ) => {
} );

if ( getExpressCheckoutData( 'button_context' ) === 'product' ) {
wcpayECE.attachProductPageEventListeners( elements );
wcpayECE.attachProductPageEventListeners( elements, eceButton );
}
},

Expand Down Expand Up @@ -414,7 +414,7 @@ jQuery( ( $ ) => {
return api.expressCheckoutECEGetSelectedProductData( data );
},

attachProductPageEventListeners: ( elements ) => {
attachProductPageEventListeners: ( elements, eceButton ) => {
// WooCommerce Deposits support.
// Trigger the "woocommerce_variation_has_changed" event when the deposit option is changed.
// Needs to be defined before the `woocommerce_variation_has_changed` event handler is set.
Expand All @@ -437,6 +437,18 @@ jQuery( ( $ ) => {

$.when( wcpayECE.getSelectedProductData() )
.then( ( response ) => {
// We do not support variable subscriptions with variations
// that require shipping and include a free trial.
if (
getExpressCheckoutData( 'product' )
.product_type === 'variable-subscription' &&
response.needs_shipping &&
response.has_free_trial
) {
eceButton.destroy();
return;
}

const isDeposits = wcpayECE.productHasDepositOption();
/**
* If the customer aborted the express checkout,
Expand All @@ -449,8 +461,11 @@ jQuery( ( $ ) => {
! wcpayECE.paymentAborted &&
getExpressCheckoutData( 'product' )
.needs_shipping === response.needs_shipping;

if ( ! isDeposits && needsShipping ) {
if (
! isDeposits &&
needsShipping &&
! ( eceButton._destroyed ?? false )
) {
elements.update( {
amount: response.total.amount,
} );
Expand Down
1 change: 1 addition & 0 deletions client/express-checkout/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export interface WCPayExpressCheckoutParams {
product: {
needs_shipping: boolean;
currency: string;
product_type: string;
shippingOptions: {
id: string;
label: string;
Expand Down
15 changes: 11 additions & 4 deletions includes/class-wc-payments-account.php
Original file line number Diff line number Diff line change
Expand Up @@ -2013,9 +2013,19 @@ private function init_stripe_onboarding( string $setup_mode, string $wcpay_conne
$collect_payout_requirements
);

$should_enable_woopay = filter_var( $onboarding_data['woopay_enabled_by_default'] ?? false, FILTER_VALIDATE_BOOLEAN );
$is_test_mode = in_array( $setup_mode, [ 'test', 'test_drive' ], true );
$account_already_exists = isset( $onboarding_data['url'] ) && false === $onboarding_data['url'];

// Only store the 'woopay_enabled_by_default' flag in a transient, to be enabled later, if
// it should be enabled and the account doesn't already exist, or we are in test mode.
if ( $should_enable_woopay && ( ! $account_already_exists || $is_test_mode ) ) {
set_transient( self::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT, $should_enable_woopay, DAY_IN_SECONDS );
}

// If an account already exists for this site and/or there is no need for KYC verifications, we're done.
// Our platform will respond with a `false` URL in this case.
if ( isset( $onboarding_data['url'] ) && false === $onboarding_data['url'] ) {
if ( $account_already_exists ) {
// Set the gateway options.
$gateway = WC_Payments::get_gateway();
$gateway->update_option( 'enabled', 'yes' );
Expand All @@ -2036,9 +2046,6 @@ private function init_stripe_onboarding( string $setup_mode, string $wcpay_conne
);
}

// We have an account that needs to be verified (has a URL to redirect the merchant to).
// Store the relevant onboarding data.
set_transient( self::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT, filter_var( $onboarding_data['woopay_enabled_by_default'] ?? false, FILTER_VALIDATE_BOOLEAN ), DAY_IN_SECONDS );
// Save the onboarding state for a day.
// This is used to verify the state when finalizing the onboarding and connecting the account.
// On finalizing the onboarding, the transient gets deleted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ public function ajax_get_selected_product_data() {
$data['needs_shipping'] = wc_shipping_enabled() && 0 !== wc_get_shipping_method_count( true ) && $product->needs_shipping();
$data['currency'] = strtolower( get_woocommerce_currency() );
$data['country_code'] = substr( get_option( 'woocommerce_default_country' ), 0, 2 );
$data['has_free_trial'] = class_exists( 'WC_Subscriptions_Product' ) ? WC_Subscriptions_Product::get_trial_length( $product ) > 0 : false;

wp_send_json( $data );
} catch ( Exception $e ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ public function get_product_data() {
$data['needs_shipping'] = ( wc_shipping_enabled() && 0 !== wc_get_shipping_method_count( true ) && $product->needs_shipping() );
$data['currency'] = strtolower( $currency );
$data['country_code'] = substr( get_option( 'woocommerce_default_country' ), 0, 2 );
$data['product_type'] = $product->get_type();

return apply_filters( 'wcpay_payment_request_product_data', $data, $product );
}
Expand All @@ -767,13 +768,9 @@ private function is_product_supported() {
// Simple subscription that needs shipping with free trials is not supported.
$is_free_trial_simple_subs = class_exists( 'WC_Subscriptions_Product' ) && $product->get_type() === 'subscription' && $product->needs_shipping() && WC_Subscriptions_Product::get_trial_length( $product ) > 0;

// Disable ECE for all variable subscriptions with free trials, as they are not currently supported. For now, ECE will be disabled for all such cases, and a solution will be addressed in a separate PR.
$is_free_trial_variable_sub = class_exists( 'WC_Subscriptions_Product' ) && $product->get_type() === 'variable-subscription' && WC_Subscriptions_Product::get_trial_length( $product ) > 0;

if (
! in_array( $product->get_type(), $this->supported_product_types(), true )
|| $is_free_trial_simple_subs
|| $is_free_trial_variable_sub
|| ( class_exists( 'WC_Pre_Orders_Product' ) && WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) // Pre Orders charge upon release not supported.
|| ( class_exists( 'WC_Composite_Products' ) && $product->is_type( 'composite' ) ) // Composite products are not supported on the product page.
|| ( class_exists( 'WC_Mix_and_Match' ) && $product->is_type( 'mix-and-match' ) ) // Mix and match products are not supported on the product page.
Expand Down
70 changes: 70 additions & 0 deletions tests/unit/test-class-wc-payments-account.php
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,76 @@ public function test_maybe_handle_onboarding_init_embedded_kyc() {
$this->wcpay_account->maybe_handle_onboarding();
}

public function test_ensure_woopay_enabled_by_default_value_set_in_sandbox_mode_kyc() {
// Arrange.
// We need to be in the WP admin dashboard.
$this->set_is_admin( true );
// Test as an admin user.
wp_set_current_user( 1 );

// Configure the request to be in sandbox mode.
$_GET['wcpay-connect'] = 'connect-from';
$_REQUEST['_wpnonce'] = wp_create_nonce( 'wcpay-connect' );
$_GET['progressive'] = 'true';
$_GET['test_mode'] = 'true';
$_GET['from'] = WC_Payments_Onboarding_Service::FROM_ONBOARDING_WIZARD;

// The Jetpack connection is in working order.
$this->mock_jetpack_connection();

$this->mock_api_client
->expects( $this->once() )
->method( 'get_onboarding_data' )
->willReturn(
[
'url' => false,
'woopay_enabled_by_default' => true,
]
);

$original_value = get_transient( WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT );

// Act.
$this->wcpay_account->maybe_handle_onboarding();

// Assert.
$this->assertFalse( $original_value );
$this->assertTrue( get_transient( WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT ) );
}

public function test_ensure_woopay_not_enabled_by_default_for_existing_live_accounts() {
// Arrange.
// We need to be in the WP admin dashboard.
$this->set_is_admin( true );
// Test as an admin user.
wp_set_current_user( 1 );

// Configure the request to be in sandbox mode.
$_GET['wcpay-connect'] = 'connect-from';
$_REQUEST['_wpnonce'] = wp_create_nonce( 'wcpay-connect' );
$_GET['progressive'] = 'true';
$_GET['from'] = WC_Payments_Onboarding_Service::FROM_ONBOARDING_WIZARD;

// The Jetpack connection is in working order.
$this->mock_jetpack_connection();

$this->mock_api_client
->expects( $this->once() )
->method( 'get_onboarding_data' )
->willReturn(
[
'url' => false,
'woopay_enabled_by_default' => true,
]
);

// Act.
$this->wcpay_account->maybe_handle_onboarding();

// Assert.
$this->assertFalse( get_transient( WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT ) );
}

public function test_maybe_handle_onboarding_init_stripe_onboarding_existing_account() {
// Arrange.
// We need to be in the WP admin dashboard.
Expand Down

0 comments on commit 9801d44

Please sign in to comment.