I created a custom registration form which works fine when used as a custom page template. I needed it as a shortcode so I created a shortcode using the function below
/* Custom shortcode */
function team_reg_form(){
require_once(ABSPATH . WPINC . '/registration.php');
global $wpdb, $user_ID;
echo '<div id="team-reg-form">';
//if the form is posted we need to validate
if ('POST' == $_SERVER['REQUEST_METHOD']) {
$user_login = $_POST['user_email'];
$user_email = $_POST['user_email'];
$billing_phone = $_POST['billing_phone'];
//initialize a WP_Errror object
$errors = new WP_Error();
//email is required
if ( isset($user_email) && $user_email == '' )
$errors->add('email_required', __('The email field is required.'));
//email needs to be a valid email
if ( isset($user_email) && !is_email($user_email) )
$errors->add('email_invalid', __('The email is not valid.'));
if(!$errors->get_error_codes())
$errors = $user_id = wp_insert_user(array('user_login' => $user_login, 'user_email' => $user_email));
update_usermeta($user_id, 'billing_phone', $billing_phone);
//update_usermeta($user_id, 'first_name', $first_name);
update_usermeta( $user_id, 'first_name', $_POST['first_name'] );
//if we still do not have any errors it was a success
if (!is_wp_error($errors)) {
wp_redirect( 'https://example.com/'); exit;
}else{//output the errors
foreach($errors->errors as $code => $error)
echo '<p>'.$error[0].'</p>';
}
}
echo '<form name="registerform" id="registerform" action="'. the_permalink().'" method="post">
<p>
<label for="first_name">'. _e('Name').'<br />
<input type="text" name="first_name" id="first_name" class="input" value="'. esc_attr(stripslashes($first_name)).'" tabindex="2" /></label>
</p>
<p>
<label for="user_email">'. _e('E-mail').'<br />
<input type="text" name="user_email" id="user_email" class="input" value="'. esc_attr(stripslashes($user_email)) .'" tabindex="2" /></label>
</p>
<p>
<label for="billing_phone">'. _e('Phone').'<br />
<input type="text" name="billing_phone" id="billing_phone" class="input" value="" tabindex="4" /></label>
</p>
'. do_action('register_form').'
<p class="submit">
<input type="submit" name="wp-submit" id="wp-submit" class="button-primary" value="'. esc_attr_e('Register').'" tabindex="100" />
</p>
</form></div>';
}
add_shortcode('teamform', 'team_reg_form');

wp_redirectwill give you a headers already sent error. It won't work, but shouldn't result in a 500. Also, shortcodes need toreturntheir content, not echo. – Milo Jan 29 at 19:46