Automattic\WooCommerce\Internal\Admin\Settings\PaymentsProviders\WooPayments

WooPaymentsService::get_onboarding_step_statuspublicWC 1.0

Get the status of an onboarding step.

Method of the class: WooPaymentsService{}

No Hooks.

Returns

String. The status of the onboarding step.

Usage

$WooPaymentsService = new WooPaymentsService();
$WooPaymentsService->get_onboarding_step_status( $step_id, $location ): string;
$step_id(string) (required)
The ID of the onboarding step.
$location(string) (required)
The location for which we are onboarding. This is an ISO 3166-1 alpha-2 country code.

WooPaymentsService::get_onboarding_step_status() code WC 10.7.0

public function get_onboarding_step_status( string $step_id, string $location ): string {
	if ( ! $this->is_valid_onboarding_step_id( $step_id ) ) {
		throw new ApiArgumentException(
			'woocommerce_woopayments_onboarding_invalid_step_id',
			esc_html__( 'Invalid onboarding step ID.', 'woocommerce' ),
			(int) WP_Http::BAD_REQUEST
		);
	}

	$meets_requirements = $this->check_onboarding_step_requirements( $step_id, $location );

	// First, determine if the step should be reported as completed based on the current state of the store.
	// The step can only be auto-completed if the requirements are met.
	if ( $meets_requirements ) {
		switch ( $step_id ) {
			case self::ONBOARDING_STEP_PAYMENT_METHODS:
				// If there is already a valid account, report the step as completed
				// since allowing the user to configure payment methods won't have any effect.
				if ( $this->has_valid_account() ) {
					return self::ONBOARDING_STEP_STATUS_COMPLETED;
				}
				break;
			case self::ONBOARDING_STEP_WPCOM_CONNECTION:
				// If we have a working WPCOM connection, report the step as completed.
				// The step can only be auto-completed if the requirements are met.
				if ( $this->has_working_wpcom_connection() ) {
					return self::ONBOARDING_STEP_STATUS_COMPLETED;
				}
				break;
			case self::ONBOARDING_STEP_TEST_ACCOUNT:
				// If the account is a valid, working test or sandbox account, the step is completed.
				if ( ( $this->has_test_account() || $this->has_sandbox_account() ) && $this->has_valid_account() && $this->has_working_account() ) {
					// Since it takes a while for the account to be fully working after the test account initialization,
					// we will force mark the step as completed here, if it is not already.
					// This is a fail-safe to guard against the case when the frontend doesn't mark the step as completed.
					// The step has no reason to be blocked or failed.
					$this->clear_onboarding_step_failed( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );
					$this->clear_onboarding_step_blocked( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );
					$this->mark_onboarding_step_completed( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );

					return self::ONBOARDING_STEP_STATUS_COMPLETED;
				}
				break;
			case self::ONBOARDING_STEP_BUSINESS_VERIFICATION:
				// The step can only be auto-completed if the requirements are met.
				// If the current account is fully onboarded and is a live account,
				// we report the business verification step as completed.
				if ( $this->has_valid_account() && $this->has_live_account() ) {
					return self::ONBOARDING_STEP_STATUS_COMPLETED;
				}
				break;
		}
	}

	// Second, try to determine the status of the onboarding step based on the step's stored statuses.
	// We take a waterfall approach: completed > blocked > failed > started > not started.
	// Reporting a completed status involves additional logic.
	switch ( $step_id ) {
		case self::ONBOARDING_STEP_WPCOM_CONNECTION:
			// Ignore any completed stored statuses because of the critical nature of the WPCOM connection.
			break;
		case self::ONBOARDING_STEP_TEST_ACCOUNT:
			// If there is a stored completed status, we respect that IF there is NO invalid test account.
			// This is the case when the user first creates a test account and then switches to live.
			// The step can only be completed if the requirements are met.
			if ( $meets_requirements &&
				$this->was_onboarding_step_marked_completed( $step_id, $location ) &&
				! ( $this->has_test_account() && ! $this->has_valid_account() )
			) {
				return self::ONBOARDING_STEP_STATUS_COMPLETED;
			}
			break;
		case self::ONBOARDING_STEP_BUSINESS_VERIFICATION:
			// The step can only be completed if the requirements are met. Otherwise, ignore the stored completed status.
			// Sanity check: we only report the completed status if there is a live account and the account is valid (i.e. completed KYC).
			if ( $meets_requirements &&
				$this->was_onboarding_step_marked_completed( $step_id, $location ) &&
				$this->has_valid_account() &&
				( $this->has_live_account() || $this->has_sandbox_account() )
			) {
				return self::ONBOARDING_STEP_STATUS_COMPLETED;
			}
			break;
		case self::ONBOARDING_STEP_PAYMENT_METHODS:
		default:
			// The step can only be completed if the requirements are met. Otherwise, ignore the stored completed status.
			if ( $meets_requirements && $this->was_onboarding_step_marked_completed( $step_id, $location ) ) {
				return self::ONBOARDING_STEP_STATUS_COMPLETED;
			}

			break;
	}
	// Blocked and failed statuses are only reported if the step's requirements are met.
	if ( $meets_requirements ) {
		if ( $this->is_onboarding_step_blocked( $step_id, $location ) ) {
			return self::ONBOARDING_STEP_STATUS_BLOCKED;
		}
		if ( $this->is_onboarding_step_failed( $step_id, $location ) ) {
			return self::ONBOARDING_STEP_STATUS_FAILED;
		}
	}
	if ( $this->was_onboarding_step_marked_started( $step_id, $location ) ) {
		// Special treatment for the test account step:
		// If the step was marked as started more than 1 minutes ago (plenty of time for the slowest of webhooks to
		// come through) and it is obviously not completed, and there is no account connected,
		// we will unmark it as started (aka clean its progress). Something went wrong with the step!
		// This is an auto-healing measure to prevent the step from being stuck in a started state indefinitely.
		if ( self::ONBOARDING_STEP_TEST_ACCOUNT === $step_id && ! $this->has_account() ) {
			$statuses          = (array) $this->get_nox_profile_onboarding_step_entry( $step_id, $location, 'statuses' );
			$started_timestamp = ! empty( $statuses[ self::ONBOARDING_STEP_STATUS_STARTED ] )
				? (int) $statuses[ self::ONBOARDING_STEP_STATUS_STARTED ]
				: 0;
			if ( $started_timestamp &&
				( $this->proxy->call_function( 'time' ) - $started_timestamp ) > 60 // 1 minute.
			) {
				$this->clean_onboarding_step_progress( $step_id, $location );

				// Record an event for the step being cleaned due to timeout.
				$this->record_event(
					self::EVENT_PREFIX . 'onboarding_step_progress_reset_due_to_timeout',
					$location,
					array(
						'step_id' => $step_id,
					)
				);

				return self::ONBOARDING_STEP_STATUS_NOT_STARTED;
			}
		}

		return self::ONBOARDING_STEP_STATUS_STARTED;
	}

	// Finally, we default to not started.
	return self::ONBOARDING_STEP_STATUS_NOT_STARTED;
}