Skip to content

Commit

Permalink
Fix WooPay auto enable for new accounts (#9549)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladolaru authored Oct 11, 2024
1 parent 2bdb6db commit 77fd16b
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 16 deletions.
4 changes: 4 additions & 0 deletions changelog/fix-9548-woopay-auto-enable
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fix

Auto-enabled WooPay for new accounts.
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,6 @@ public function get_embedded_kyc_session( WP_REST_Request $request ) {
$account_session['locale'] = get_user_locale();
}

// Set the onboarding in progress option.
$this->onboarding_service->set_embedded_kyc_in_progress();

return rest_ensure_response( $account_session );
}

Expand Down
12 changes: 7 additions & 5 deletions includes/class-wc-payments-account.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class WC_Payments_Account {
const ONBOARDING_DISABLED_TRANSIENT = 'wcpay_on_boarding_disabled';
const ONBOARDING_STARTED_TRANSIENT = 'wcpay_on_boarding_started';
const ONBOARDING_STATE_TRANSIENT = 'wcpay_stripe_onboarding_state';
const WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT = 'woopay_enabled_by_default';
const EMBEDDED_KYC_IN_PROGRESS_OPTION = 'wcpay_onboarding_embedded_kyc_in_progress';
const ERROR_MESSAGE_TRANSIENT = 'wcpay_error_message';
const INSTANT_DEPOSITS_REMINDER_ACTION = 'wcpay_instant_deposit_reminder';
Expand Down Expand Up @@ -1607,7 +1608,7 @@ private function cleanup_on_account_reset() {
delete_transient( self::ONBOARDING_STATE_TRANSIENT );
delete_transient( self::ONBOARDING_STARTED_TRANSIENT );
delete_option( self::EMBEDDED_KYC_IN_PROGRESS_OPTION );
delete_transient( 'woopay_enabled_by_default' );
delete_transient( self::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT );

// Clear the cache to avoid stale data.
$this->clear_cache();
Expand Down Expand Up @@ -1899,7 +1900,8 @@ private function init_stripe_onboarding( string $setup_mode, string $wcpay_conne

// Clean up any existing onboarding state.
delete_transient( self::ONBOARDING_STATE_TRANSIENT );
delete_option( self::EMBEDDED_KYC_IN_PROGRESS_OPTION );
// Clear the embedded KYC in progress option, since the onboarding flow is now complete.
$this->onboarding_service->clear_embedded_kyc_in_progress();

return add_query_arg(
[ 'wcpay-connection-success' => '1' ],
Expand All @@ -1909,7 +1911,7 @@ 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( 'woopay_enabled_by_default', isset( $onboarding_data['woopay_enabled_by_default'] ) ?? false, DAY_IN_SECONDS );
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 All @@ -1926,9 +1928,9 @@ public function maybe_activate_woopay() {
return;
}

if ( get_transient( 'woopay_enabled_by_default' ) ) {
if ( get_transient( self::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT ) ) {
WC_Payments::get_gateway()->update_is_woopay_enabled( true );
delete_transient( 'woopay_enabled_by_default' );
delete_transient( self::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT );
}
}

Expand Down
19 changes: 15 additions & 4 deletions includes/class-wc-payments-onboarding-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@ function () use ( $locale ) {
*
* @return array Session data.
*
* @throws API_Exception
* @throws API_Exception|Exception
*/
public function create_embedded_kyc_session( array $self_assessment_data, bool $progressive = false ): array {
if ( ! $this->payments_api_client->is_server_connected() ) {
return [];
}

$setup_mode = WC_Payments::mode()->is_live() ? 'live' : 'test';

// Make sure the onboarding test mode DB flag is set.
Expand Down Expand Up @@ -193,6 +194,16 @@ public function create_embedded_kyc_session( array $self_assessment_data, bool $
return [];
}

// Set the embedded KYC in progress flag.
$this->set_embedded_kyc_in_progress();

// Remember if we should enable WooPay by default.
set_transient(
WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT,
filter_var( $account_session['woopay_enabled_by_default'] ?? false, FILTER_VALIDATE_BOOLEAN ),
DAY_IN_SECONDS
);

return [
'clientSecret' => $account_session['client_secret'] ?? '',
'expiresAt' => $account_session['expires_at'] ?? 0,
Expand Down Expand Up @@ -230,7 +241,7 @@ public function finalize_embedded_kyc( string $locale, string $source, array $ac
throw new API_Exception( __( 'Failed to finalize onboarding session.', 'woocommerce-payments' ), 'wcpay-onboarding-finalize-error', 400 );
}

// Clear the onboarding in progress option, since the onboarding flow is now complete.
// Clear the embedded KYC in progress option, since the onboarding flow is now complete.
$this->clear_embedded_kyc_in_progress();

return [
Expand Down Expand Up @@ -322,7 +333,7 @@ public function add_admin_body_classes( string $classes = '' ): string {
}

/**
* Get account data for onboarding from self assestment data.
* Get account data for onboarding from self assessment data.
*
* @param string $setup_mode Setup mode.
* @param array $self_assessment_data Self assessment data.
Expand Down Expand Up @@ -424,7 +435,7 @@ public function get_onboarding_user_data(): array {
* @return bool True if embedded KYC is in progress, false otherwise.
*/
public function is_embedded_kyc_in_progress(): bool {
return in_array( get_option( WC_Payments_Account::EMBEDDED_KYC_IN_PROGRESS_OPTION, 'no' ), [ 'yes', '1' ], true );
return filter_var( get_option( WC_Payments_Account::EMBEDDED_KYC_IN_PROGRESS_OPTION, 'no' ), FILTER_VALIDATE_BOOLEAN );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,6 @@ public function test_get_embedded_kyc_session() {
$kyc_session
);

$this->mock_onboarding_service
->expects( $this->once() )
->method( 'set_embedded_kyc_in_progress' );

$request = new WP_REST_Request( 'GET' );
$request->set_query_params(
[
Expand Down
116 changes: 116 additions & 0 deletions tests/unit/test-class-wc-payments-onboarding-service.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use PHPUnit\Framework\MockObject\MockObject;
use WCPay\Constants\Country_Code;
use WCPay\Database_Cache;
use WCPay\Exceptions\API_Exception;

/**
* WC_Payments_Onboarding_Service unit tests.
Expand Down Expand Up @@ -148,6 +149,121 @@ public function test_filters_registered_properly() {
$this->assertNotFalse( has_filter( 'admin_body_class', [ $this->onboarding_service, 'add_admin_body_classes' ] ) );
}

public function test_create_embedded_kyc_session() {
// Arrange.
$this->mock_api_client
->method( 'is_server_connected' )
->willReturn( true );

$expected_account_session = [
'client_secret' => 'secret',
'expires_at' => time() + 3600,
'account_id' => 'acc_123',
'is_live' => true,
'account_created' => true,
'publishable_key' => 'pk_test_123',
'woopay_enabled_by_default' => true,
];

$this->mock_api_client
->method( 'initialize_onboarding_embedded_kyc' )
->willReturn( $expected_account_session );

$this->onboarding_service->clear_embedded_kyc_in_progress();

delete_transient( WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT );

// Act.
$result = $this->onboarding_service->create_embedded_kyc_session( [], false );

// Assert.
$this->assertEquals( $expected_account_session['client_secret'], $result['clientSecret'] );
$this->assertEquals( $expected_account_session['expires_at'], $result['expiresAt'] );
$this->assertEquals( $expected_account_session['account_id'], $result['accountId'] );
$this->assertEquals( $expected_account_session['is_live'], $result['isLive'] );
$this->assertEquals( $expected_account_session['account_created'], $result['accountCreated'] );
$this->assertEquals( $expected_account_session['publishable_key'], $result['publishableKey'] );

$this->assertTrue( $this->onboarding_service->is_embedded_kyc_in_progress() );
$this->assertTrue( get_transient( WC_Payments_Account::WOOPAY_ENABLED_BY_DEFAULT_TRANSIENT ) );
}

public function test_create_embedded_kyc_session_no_wpcom_connection() {
// Arrange.
$this->mock_api_client
->method( 'is_server_connected' )
->willReturn( false );

// Act.
$result = $this->onboarding_service->create_embedded_kyc_session( [], false );

// Assert.
$this->assertEmpty( $result );
}

public function test_finalize_embedded_kyc() {
// Arrange.
$this->mock_api_client
->method( 'is_server_connected' )
->willReturn( true );

$expected_result = [
'success' => true,
'account_id' => 'acc_id',
'details_submitted' => true,
'mode' => 'test',
'promotion_id' => 'promotion_id',
];
$this->mock_api_client
->method( 'finalize_onboarding_embedded_kyc' )
->willReturn( $expected_result );

$this->onboarding_service->set_embedded_kyc_in_progress();

// Act.
$result = $this->onboarding_service->finalize_embedded_kyc( 'en_US', 'source', [] );

// Assert.
$this->assertEquals( $expected_result['success'], $result['success'] );
$this->assertEquals( $expected_result['account_id'], $result['account_id'] );
$this->assertEquals( $expected_result['details_submitted'], $result['details_submitted'] );
$this->assertEquals( $expected_result['mode'], $result['mode'] );
$this->assertEquals( $expected_result['promotion_id'], $result['promotion_id'] );

$this->assertFalse( $this->onboarding_service->is_embedded_kyc_in_progress() );
}

public function test_finalize_embedded_kyc_no_wpcom_connection() {
// Arrange.
$this->mock_api_client
->method( 'is_server_connected' )
->willReturn( false );

// Act.
$result = $this->onboarding_service->finalize_embedded_kyc( 'en_US', 'source', [] );

// Assert.
$this->assertEquals( [ 'success' => false ], $result );
}

public function test_finalize_embedded_kyc_no_success() {
// Arrange.
$this->mock_api_client
->method( 'is_server_connected' )
->willReturn( true );

$this->mock_api_client
->method( 'finalize_onboarding_embedded_kyc' )
->willReturn( [ 'success' => false ] );

// Assert.
$this->expectException( API_Exception::class );
$this->expectExceptionMessage( 'Failed to finalize onboarding session.' );

// Act.
$this->onboarding_service->finalize_embedded_kyc( 'en_US', 'source', [] );
}

public function test_get_cached_business_types_with_no_server_connection() {
$this->mock_api_client
->expects( $this->once() )
Expand Down

0 comments on commit 77fd16b

Please sign in to comment.