diff --git a/common/djangoapps/student/tests/test_microsite.py b/common/djangoapps/student/tests/test_microsite.py
index b447ad3a13c10e2b8c2d08eb2ea18f2141b07bb1..d76aa9a72a85aea9bc4630ed69df9d66556c9521 100644
--- a/common/djangoapps/student/tests/test_microsite.py
+++ b/common/djangoapps/student/tests/test_microsite.py
@@ -4,8 +4,24 @@ Test for User Creation from Micro-Sites
 from django.test import TestCase
 from student.models import UserSignupSource
 import mock
+import json
 from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
 
+FAKE_MICROSITE = {
+    "SITE_NAME": "openedx.localhost",
+    "REGISTRATION_EXTRA_FIELDS": {
+        "address1": "required",
+        "city": "required",
+        "state": "required",
+        "country": "required",
+        "company": "required",
+        "title": "required"
+    },
+    "extended_profile_fields": [
+        "address1", "state", "company", "title"
+    ]
+}
 
 def fake_site_name(name, default=None):  # pylint: disable=W0613
     """
@@ -14,8 +30,13 @@ def fake_site_name(name, default=None):  # pylint: disable=W0613
     if name == 'SITE_NAME':
         return 'openedx.localhost'
     else:
-        return None
+        return default
 
+def fake_microsite_get_value(name, default=None):  # pylint: disable=W0613
+    """
+    create a fake microsite site name
+    """
+    return FAKE_MICROSITE.get(name, default)
 
 class TestMicrosite(TestCase):
     """Test for Account Creation from a white labeled Micro-Sites"""
@@ -30,6 +51,14 @@ class TestMicrosite(TestCase):
             "honor_code": "true",
             "terms_of_service": "true",
         }
+        self.extended_params = dict(self.params.items() + {
+            "address1": "foo",
+            "city": "foo",
+            "state": "foo",
+            "country": "foo",
+            "company": "foo",
+            "title": "foo"
+        }.items())
 
     @mock.patch("microsite_configuration.microsite.get_value", fake_site_name)
     def test_user_signup_source(self):
@@ -49,3 +78,27 @@ class TestMicrosite(TestCase):
         response = self.client.post(self.url, self.params)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(len(UserSignupSource.objects.filter(site='openedx.localhost')), 0)
+
+    @mock.patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
+    def test_user_signup_missing_enhanced_profile(self):
+        """
+        test to create a user form the microsite but don't provide any of the microsite specific
+        profile information
+        """
+        response = self.client.post(self.url, self.params)
+        self.assertEqual(response.status_code, 400)
+
+    @mock.patch("microsite_configuration.microsite.get_value", fake_microsite_get_value)
+    def test_user_signup_including_enhanced_profile(self):
+        """
+        test to create a user form the microsite but don't provide any of the microsite specific
+        profile information
+        """
+        response = self.client.post(self.url, self.extended_params)
+        self.assertEqual(response.status_code, 200)
+        user = User.objects.get(username=self.username)
+        meta = json.loads(user.profile.meta)
+        self.assertEqual(meta['address1'], 'foo')
+        self.assertEqual(meta['state'], 'foo')
+        self.assertEqual(meta['company'], 'foo')
+        self.assertEqual(meta['title'], 'foo')
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 4ad74eb2281cc6da1c5979fff0898a911eca1088..b26213624fa4561e3461229144b940809f1cf2eb 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -6,6 +6,7 @@ import logging
 import re
 import uuid
 import time
+import json
 from collections import defaultdict
 from pytz import UTC
 
@@ -1039,7 +1040,7 @@ def user_signup_handler(sender, **kwargs):  # pylint: disable=W0613
             log.info(u'user {} originated from a white labeled "Microsite"'.format(kwargs['instance'].id))
 
 
-def _do_create_account(post_vars):
+def _do_create_account(post_vars, extended_profile=None):
     """
     Given cleaned post variables, create the User and UserProfile objects, as well as the
     registration for this user.
@@ -1089,6 +1090,10 @@ def _do_create_account(post_vars):
     profile.country = post_vars.get('country')
     profile.goals = post_vars.get('goals')
 
+    # add any extended profile information in the denormalized 'meta' field in the profile
+    if extended_profile:
+        profile.meta = json.dumps(extended_profile)
+
     try:
         profile.year_of_birth = int(post_vars['year_of_birth'])
     except (ValueError, KeyError):
@@ -1115,7 +1120,12 @@ def create_account(request, post_override=None):  # pylint: disable-msg=too-many
     js = {'success': False}  # pylint: disable-msg=invalid-name
 
     post_vars = post_override if post_override else request.POST
-    extra_fields = getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
+
+    # allow for microsites to define their own set of required/optional/hidden fields
+    extra_fields = microsite.get_value(
+        'REGISTRATION_EXTRA_FIELDS',
+        getattr(settings, 'REGISTRATION_EXTRA_FIELDS', {})
+    )
 
     if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH') and pipeline.running(request):
         post_vars = dict(post_vars.items())
@@ -1188,7 +1198,7 @@ def create_account(request, post_override=None):  # pylint: disable-msg=too-many
         else:
             min_length = 2
 
-        if len(post_vars[field_name]) < min_length:
+        if field_name not in post_vars or len(post_vars[field_name]) < min_length:
             error_str = {
                 'username': _('Username must be minimum of two characters long'),
                 'email': _('A properly formatted e-mail is required'),
@@ -1204,7 +1214,12 @@ def create_account(request, post_override=None):  # pylint: disable-msg=too-many
                 'city': _('A city is required'),
                 'country': _('A country is required')
             }
-            js['value'] = error_str[field_name]
+
+            if field_name in error_str:
+                js['value'] = error_str[field_name]
+            else:
+                js['value'] = _('You are missing one or more required fields')
+
             js['field'] = field_name
             return JsonResponse(js, status=400)
 
@@ -1248,10 +1263,22 @@ def create_account(request, post_override=None):  # pylint: disable-msg=too-many
             js['field'] = 'password'
             return JsonResponse(js, status=400)
 
+    # allow microsites to define 'extended profile fields' which are
+    # captured on user signup (for example via an overriden registration.html)
+    # and then stored in the UserProfile
+    extended_profile_fields = microsite.get_value('extended_profile_fields', [])
+    extended_profile = None
+
+    for field in extended_profile_fields:
+        if field in post_vars:
+            if not extended_profile:
+                extended_profile = {}
+            extended_profile[field] = post_vars[field]
+
     # Ok, looks like everything is legit.  Create the account.
     try:
         with transaction.commit_on_success():
-            ret = _do_create_account(post_vars)
+            ret = _do_create_account(post_vars, extended_profile)
     except AccountValidationError as e:
         return JsonResponse({'success': False, 'value': e.message, 'field': e.field}, status=400)