Set default form values after AJAX callback OK I know this question has been asked multiple times from people in different ways but I haven't been able to pinpoint my exact use case or solution. 

I have a registration form that I want to prefill the default values after the user selects an option from a select list. After they select an option, AJAX fires off to see if the user is in our CRM, and runs a series of code to look up information. I then want that found information to show in the various form fields on the page. 

Couple key things to point out that I often find in other solutions that do not work for me:


The user is NOT submitting. They are still doing work on the form, the first form field sets up their experience going forward. 
Setting the field info in $form_state['values'] doesn't work. Nothing is set. 
Settings the field info $form_state['input'] does work, but then if a user changes any of the values in the fields, that new change isn't set. 


Here is a stripped down example of what is being done. 

function ces_user_registration_form_commerce_checkout_form_registration_alter(&amp;$form, &amp;$form_state, $form_id) {
    foreach ($form['registration_information']['register_entities'] as $name =&gt; $data) {
        foreach($form['registration_information'][$name] as $subname =&gt; $subdata) {
            $form['registration_information'][$name][$subname]['register_for']['#ajax'] = array(
                'wrapper' =&gt; 'commerce-checkout-form-registration',
                'callback' =&gt; 'ces_user_registration_form_register_for_ajax_callback',
                'method' =&gt; 'replace'
            );
            // run our code for comparing user values with CRM
            // return object with CRM data
            // below are example static value settings that I have


            // This works after AJAX is called, but the field isn't visually filled in for the user, 
            $form['registration_information'][$name][$subname]['field_first_name']['und'][0]['value']['#default_value'] = "travis";

            // This works after AJAX is called, but changes to the field are not saved or recognized so we save their old value
            $form_state['input']['registration_information'][$name][$subname]['field_first_name']['und'][0]['value'] = "travis";

        }
    }
}


and the callback

function ces_user_registration_form_register_for_ajax_callback($form, &amp;$form_state) {
    foreach ($form['registration_information']['register_entities'] as $name =&gt; $data) {
        foreach($form['registration_information'][$name] as $subname =&gt; $subdata) {
            if(!empty($form_state['values']['registration_information'][$name][$subname]['register_for']) &amp;&amp; $form_state['values']['registration_information'][$name][$subname]['register_for'] == 'registration_registrant_type_me' ){

                // I tried moving the CRM code down here instead, but no changes
                // run our code for comparing user values with CRM
                // return object with CRM data
                // below are example static value settings that I have tried

                // doesn't work
                $form['registration_information'][$name][$subname]['field_first_name']['und'][0]['value']['#default_value'] = "travis";

                // doesn't work
                $form_state['values']['registration_information'][$name][$subname]['field_first_name']['und'][0]['value'] = "travis";

                // doesn't work
                $form_state['input']['registration_information'][$name][$subname]['field_first_name']['und'][0]['value'] = "travis";
            }
        }
    }
    return $form
}
I finally found a way to do this, though it appears this isn't the best way to do it - but it works. 

You can not set #default_value for a field if the field is set in $form_state['input']['field_name'].

So before I try to set the field to the newly generated value, if I put this before then I can reset the default value. 

unset($form_state['input']['registration_information'][$name][$subname]['field_name']);