public function onboarding_test_account_init( string $location, ?string $source = self::SESSION_ENTRY_DEFAULT ): array {
$this->check_if_onboarding_step_action_is_acceptable( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );
// Nothing to do if we already have a connected test account.
if ( $this->has_test_account() ) {
throw new ApiException(
'woocommerce_woopayments_test_account_already_exists',
esc_html__( 'A test account is already set up.', 'woocommerce' ),
(int) WP_Http::FORBIDDEN
);
}
// Nothing to do if there is a connected account, but it is not a test account.
if ( $this->has_account() ) {
// Mark the onboarding step as completed, if it is not already.
$this->mark_onboarding_step_completed( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );
throw new ApiException(
'woocommerce_woopayments_onboarding_action_error',
esc_html__( 'An account is already set up. Reset the onboarding first.', 'woocommerce' ),
(int) WP_Http::FORBIDDEN
);
}
// Clear any previous failed status for the step.
$this->clear_onboarding_step_failed( self::ONBOARDING_STEP_TEST_ACCOUNT, $location );
$configured_payment_methods = $this->get_nox_profile_onboarding_step_data_entry( self::ONBOARDING_STEP_PAYMENT_METHODS, $location, 'payment_methods', array() );
// Ensure the payment gateways logic is initialized in case actions need to be taken on payment gateway changes.
WC()->payment_gateways();
$source = $this->validate_onboarding_source( $source );
// Lock the onboarding to prevent concurrent actions.
$this->set_onboarding_lock();
try {
// Call the WooPayments API to initialize the test account.
$response = $this->proxy->call_static(
Utils::class,
'rest_endpoint_post_request',
'/wc/v3/payments/onboarding/test_drive_account/init',
array(
'country' => $location,
'capabilities' => $configured_payment_methods,
'source' => $source,
'from' => self::FROM_NOX_IN_CONTEXT,
)
);
} catch ( Exception $e ) {
// Catch any exceptions to allow for proper error handling and onboarding unlock.
$response = new WP_Error(
'woocommerce_woopayments_onboarding_client_api_exception',
esc_html__( 'An unexpected error happened while initializing the test account.', 'woocommerce' ),
array(
'code' => $e->getCode(),
'message' => $e->getMessage(),
'trace' => $e->getTrace(),
)
);
}
// Unlock the onboarding after the API call finished or errored.
$this->clear_onboarding_lock();
if ( is_wp_error( $response ) ) {
// Mark the onboarding step as failed.
$this->mark_onboarding_step_failed(
self::ONBOARDING_STEP_TEST_ACCOUNT,
$location,
array(
'code' => $response->get_error_code(),
'message' => $response->get_error_message(),
'context' => $response->get_error_data(),
)
);
throw new ApiException(
'woocommerce_woopayments_onboarding_client_api_error',
esc_html( $response->get_error_message() ),
(int) WP_Http::FAILED_DEPENDENCY,
map_deep( (array) $response->get_error_data(), 'esc_html' )
);
}
if ( ! is_array( $response ) || empty( $response['success'] ) ) {
// Mark the onboarding step as failed.
$this->mark_onboarding_step_failed(
self::ONBOARDING_STEP_TEST_ACCOUNT,
$location,
array(
'code' => 'malformed_response',
'message' => esc_html__( 'Received an unexpected response from the platform.', 'woocommerce' ),
'context' => array(
'response' => $response,
),
)
);
throw new ApiException(
'woocommerce_woopayments_onboarding_client_api_error',
esc_html__( 'Failed to initialize the test account.', 'woocommerce' ),
(int) WP_Http::FAILED_DEPENDENCY
);
}
// Record an event for the test account being initialized.
$payment_methods_enabled = array();
$payment_methods_disabled = array();
if ( ! empty( $configured_payment_methods ) && is_array( $configured_payment_methods ) ) {
foreach ( $configured_payment_methods as $pm_id => $enabled ) {
if ( ! is_string( $pm_id ) || ! is_bool( $enabled ) ) {
continue; // Skip invalid entries.
}
if ( $enabled ) {
$payment_methods_enabled[] = sanitize_key( $pm_id );
} else {
$payment_methods_disabled[] = sanitize_key( $pm_id );
}
}
}
$payment_methods_enabled = array_unique( $payment_methods_enabled );
$payment_methods_disabled = array_unique( $payment_methods_disabled );
$event_props = array(
'payment_methods_enabled' => implode( ', ', $payment_methods_enabled ),
'payment_methods_disabled' => implode( ', ', $payment_methods_disabled ),
'source' => $source,
);
$this->record_event(
self::EVENT_PREFIX . 'onboarding_test_account_init',
$location,
$event_props
);
return $response;
}