diff --git a/src/memberdb/account.py b/src/memberdb/account.py
index 5f911c0f1cd3747cdce27e480f708ca32356af96..216358c0b7800039f28efb10d317affe828a34ff 100644
--- a/src/memberdb/account.py
+++ b/src/memberdb/account.py
@@ -45,8 +45,7 @@ class AccountForm(MyModelForm):
 			pass
 		super().clean();
 
-	def save(self):
-		return
+
 
 class EmailForm(MyModelForm):
 	forward = forms.BooleanField(required=False)
@@ -64,7 +63,7 @@ class EmailForm(MyModelForm):
 		if self['forward'].value() == True:
 			try:
 				if (len(self['email_address'].value()) == 0):
-					self.add_error('email_address', 'Email field cannot be left blankL.')
+					self.add_error('email_address', 'Email field cannot be left blank.')
 				if (self['email_address'].value().split('@')[1] in ["ucc.asn.au", "ucc.gu.uwa.edu.au"]):
 					self.add_error('email_address', 'Forwarding address cannot be the same as your account address.')
 			except:
@@ -121,12 +120,22 @@ class AccountView(MyWizardView):
 
 	def done(self, form_list, form_dict, **kwargs):
 
-		# create the user and save their username if successfull
-		if create_ad_user(self.get_cleaned_data_for_step('0'), self.object):
-			form_list[0].save()
-
 
-		messages.success(self.request, 'Your membership renewal has been submitted.')
+		# create the user and save their username if successfull
+		try:
+			if create_ad_user(self.get_cleaned_data_for_step('0'), self.object):
+				form_dict['0'].save()
+
+			make_home(self.get_cleaned_data_for_step('1'), self.object)
+			make_dispense_account(self.object.username, self.get_cleaned_data_for_step('2')['pin'])
+			subscribe_to_list(self.object)
+		except Exception as e:
+			messages.error(self.request,'Account creation failed for %s', self.object)
+			messages.error(self.request, e)
+			raise #DEBUG
+
+		else:
+			messages.success(self.request, 'An account has been successfully created for %s.' % self.object)
 		return HttpResponseRedirect(reverse("admin:memberdb_membership_changelist"))
 
 		#return accountProgressView(self.request, m)
diff --git a/src/memberdb/account_backend.py b/src/memberdb/account_backend.py
index a66364c1eb36981ea2af36143cb650d641f97893..697f95a4a56939e9f8784e7915e36ef20a7f236d 100644
--- a/src/memberdb/account_backend.py
+++ b/src/memberdb/account_backend.py
@@ -31,7 +31,7 @@ ldap_user_dn = getattr(settings, 'LDAP_USER_SEARCH_DN')
 ldap_base_dn = getattr(settings, 'LDAP_BASE_DN')
 ldap_bind_dn = getattr(settings, 'LDAP_BIND_DN')
 ldap_bind_secret = getattr(settings, 'LDAP_BIND_SECRET')
-make_home_cmd = "sudo python3 root_actions.py" 
+make_home_cmd = ["sudo", "python3", "root_actions.py"] 
 make_mail_cmd = 'ssh -i %s root@mooneye "/usr/local/mailman/bin/add_members" -r- ucc-announce <<< %s@ucc.asn.au'
 make_mail_key = './mooneye.key'
 
@@ -206,7 +206,8 @@ def create_ad_user(form_data, member):
 		result = get_maxuid()
 	except:
 		log.error("LDAP: cannot find base uid")
-		return False
+		raise
+
 
 	maxuid = int(result.msSFU30MaxUidNumber.value)
 
@@ -236,7 +237,7 @@ def create_ad_user(form_data, member):
 	# sanity check: make sure the uid is free
 	if subprocess.call(["id", newuid], stderr=subprocess.DEVNULL) == 0:
 		log.error("LDAP: uid already taken")
-		return False
+		raise ValueError
 
 	# create the new user struct
 	objclass = ['top','posixAccount','person','organizationalPerson','user']
@@ -261,24 +262,31 @@ def create_ad_user(form_data, member):
 	result = ld.add(dn, objclass, attrs)
 	if not result:
 		log.error("LDAP: user add failed")
-		return False
+		raise LDAPOperationsErrorResult
 
 	# set maxuid
 	result = ld.modify(maxuid_dn, {'msSFU30MaxUidNumber': [(MODIFY_REPLACE, newuid)]})
 	if not result:
-		log.warning("LDAP: user created but msSFU30MaxUidNumber not update")
+		log.warning("LDAP: user created but msSFU30MaxUidNumber not updated")
 
 	ld.unbind();
 	return True;
 
-def make_home(member,formdata):
+def make_home(formdata, member):
 	user = member.username
 	mail = formdata['email_address'] if formdata['forward'] else ""
-	return subprocess.call(make_home_cmd, user, mail)
-
+	result = subprocess.call(make_home_cmd + [user, mail])
+	if result == 0:
+		return True
+	else:
+		raise CalledProcessError
 
 def subscribe_to_list(member):
-	return os.system(make_mail_cmd % (make_mail_key, member.username))
+	result = os.system(make_mail_cmd % (make_mail_key, member.username))
+	if result == 0:
+		return True
+	else:
+		raise CalledProcessError
 
 def set_pin(member, pin):
 	return
diff --git a/src/memberdb/forms.py b/src/memberdb/forms.py
index f9ff1d4bc546436633f348923d48a90a5f6c40d1..340c30739fe878eb5518703ee94632ec3708aaba 100644
--- a/src/memberdb/forms.py
+++ b/src/memberdb/forms.py
@@ -23,4 +23,4 @@ class MyForm(forms.Form):
 class MemberHomeForm(MyModelForm):
     class Meta:
         model = Member
-        fields = ['display_name', 'email_address', 'phone_number']
+        fields = [ 'email_address', 'phone_number']
diff --git a/src/memberdb/models.py b/src/memberdb/models.py
index d5ba6f1484a5fffca285336dcb8a6d7155843b86..57dddd6000a3d874f0a9cc427a3d328490323812 100644
--- a/src/memberdb/models.py
+++ b/src/memberdb/models.py
@@ -5,6 +5,7 @@ from django.core.management.utils import get_random_string
 from django.urls import reverse
 
 from squarepay.dispense import get_item_price
+import subprocess
 
 import ldap
 
@@ -110,6 +111,13 @@ PAYMENT_METHODS = [
 	('', 'No payment')
 ]
 
+ID_TYPES = [
+	('student', 'Student ID'),
+	('drivers', 'Drivers licence'),
+	('passport', 'Passport'),
+	('Other', 'Other ID'),
+]
+
 ACCOUNT_STATUS = [
 		'enabled',
 		'disabled',
@@ -124,15 +132,15 @@ class IncAssocMember (models.Model):
 	Note: these data should only be changed administratively or with suitable validation since it must be up to date & accurate.
 	"""
 
-	first_name      = models.CharField ('First name', max_length=200)
-	last_name       = models.CharField ('Surname', max_length=200)
-	email_address   = models.EmailField ('Email address', blank=False)
+	first_name      = models.CharField ('Given Name', max_length=200)
+	last_name       = models.CharField ('Other Names', max_length=200)
+	email_address   = models.EmailField ('Contact email', blank=False)
 	updated         = models.DateTimeField ('IncA. info last updated', auto_now=True)
 	created         = models.DateTimeField ('When created', auto_now_add=True)
 
 	def __str__ (self):
 		return "%s %s <%s>" % (self.first_name, self.last_name, self.email_address)
-	
+
 	class Meta:
 		verbose_name = "Incorporations Act member data"
 		verbose_name_plural = verbose_name
@@ -145,13 +153,16 @@ class Member (IncAssocMember):
 	Note: Privacy laws are a thing, unless people allow it then we cannot provide this info to members.
 	"""
 
+
+
 	# data to be entered by user and validated (mostly) manually
 	display_name    = models.CharField ('Display name', max_length=200)
-	username        = models.SlugField ('Username', max_length=32, null=False, blank=False, unique=True, validators=[RegexValidator(regex='^[a-z0-9._-]+$')])
+	username        = models.SlugField ('Username', max_length=32, null=True, blank=True, unique=True, validators=[RegexValidator(regex='^[a-z0-9._-]*$')])
 	phone_number    = models.CharField ('Phone number', max_length=20, blank=False, validators=[RegexValidator(regex='^\+?[0-9() -]+$')])
 	is_student      = models.BooleanField ('Student', default=True, blank=True, help_text="Tick this box if you are a current student at a secondary or tertiary institution in WA")
 	is_guild        = models.BooleanField ('UWA Guild member', default=True, blank=True)
-	id_number       = models.CharField ('Student email or Drivers License', max_length=255, blank=False, help_text="Student emails should end with '@student.*.edu.au' and drivers licences should be in the format '<AU state> 1234567'")
+	id_number       = models.CharField ('Student number or other ID', max_length=255, blank=False, help_text="")
+	id_desc			= models.CharField  ('Form of ID provided', max_length=255, blank=False, help_text="Please describe the type of identification provided", choices=ID_TYPES, default="student")
 
 	# data used internally by the system, not to be touched, seen or heard (except when it is)
 	member_updated  = models.DateTimeField ('Internal UCC info last updated', auto_now=True)
@@ -160,9 +171,15 @@ class Member (IncAssocMember):
 	studnt_confirm  = models.BooleanField ('Student status confirmed', null=False, editable=False, default=False)
 	guild_confirm   = models.BooleanField ('Guild status confirmed', null=False, editable=False, default=False)
 
+	has_account		= models.BooleanField ('Has AD account', null=False, editable=False, default=False)
+
 	# account info
-	def get_account_status(self):
-		return;
+	def get_uid(self):
+		result, uid = subprocess.getstatusoutput(["id", "-u", self.username])
+		if (result == 0):
+			return uid;
+		else:
+			return None;
 
 	def __str__ (self):
 		if (self.display_name != "%s %s" % (self.first_name, self.last_name)):
diff --git a/src/memberdb/register.py b/src/memberdb/register.py
index 60f1ba38e8820a922afe2098a1089eea8baca7e0..5058358275c863646c400bb85d604e8ad3508f77 100644
--- a/src/memberdb/register.py
+++ b/src/memberdb/register.py
@@ -23,119 +23,147 @@ First step: enter an email address and some details (to fill at least a Member m
 see https://docs.djangoproject.com/en/2.1/ref/models/fields/#error-messages
 and https://docs.djangoproject.com/en/2.1/ref/forms/fields/#error-messages
 """
-class RegisterForm(MyModelForm):
-    confirm_email   = forms.EmailField(label='Confirm your email address', required=False)
-    agree_tnc       = forms.BooleanField(label='I agree to the terms & conditions', required=True, help_text=mark_safe(
-        "You agree to abide by the UCC Constitution, rulings of the UCC Committee, UCC and "
-        "UWA’s Network Usage Guidelines and that you will be subscribed to the UCC Mailing List. <br>"
-        '<b>Policies can be found <a href="https://www.ucc.asn.au/infobase/policies.ucc">here</a>.</b>'))
-    membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=False))
-
-    class Meta:
-        model = Member
-        fields = ['first_name', 'last_name', 'username', 'phone_number', 'is_student', 'is_guild', 'id_number', 'email_address']
-        error_messages = {
-            'username': {
-                'unique': 'This username is already taken, please pick another one.',
-                'invalid': 'Please pick a username with only lowercase letters and numbers'
-            }
-        }
-    
-    def clean(self):
-        try:
-            if (self['email_address'].value() != self['confirm_email'].value()):
-                self.add_error('email_address', 'Email addresses must match.')
-        except:
-            pass
-        super().clean();
-
-    def save(self, commit=True):
-        # get the Member model instance (ie. a record in the Members table) based on submitted form data 
-        m = super().save(commit=False)
-        if (m.display_name == ""):
-            m.display_name = "%s %s" % (m.first_name, m.last_name);
-        # must save otherwise membership creation will fail
-        m.save()
-
-        # now create a corresponding Membership (marked as pending / not accepted, mostly default values)
-        ms = make_pending_membership(m)
-
-        if (commit):
-            ms.save();
-        return m, ms
-
-class RenewForm(RegisterForm):
-    confirm_email = None
-    membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=True))
-
-    class Meta(RegisterForm.Meta):
-        fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'email_address']
-
-    def save(self, commit=True):
-        m, ms = super().save(commit=False)
-        m.username = self.request.user.username
-        if (commit):
-            m.save()
-            ms.save()
-        return m, ms
+class RegisterRenewForm(MyModelForm):
+	confirm_email   = forms.EmailField(label='Confirm your email address', required=False)
+	agree_tnc       = forms.BooleanField(label='I agree to the terms & conditions', required=True, help_text=mark_safe(
+		"You agree to abide by the UCC Constitution, rulings of the UCC Committee, UCC and "
+		"UWA’s Network Usage Guidelines and that you will be subscribed to the UCC Mailing List. <br>"
+		'<b>Policies can be found <a href="https://www.ucc.asn.au/infobase/policies.ucc">here</a>.</b>'))
+	membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=False))
+
+	class Meta:
+		model = Member
+		fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']
+		error_messages = {
+			'username': {
+				'unique': 'This username is already taken, please pick another one.',
+				'invalid': 'Please pick a username with only lowercase letters and numbers'
+			}
+		}
+
+	def clean(self):
+		try:
+			if (self['email_address'].value() != self['confirm_email'].value()):
+				self.add_error('email_address', 'Email addresses must match.')
+			if (self['email_address'].value().split('@')[1] in ["ucc.asn.au", "ucc.gu.uwa.edu.au"]):
+					self.add_error('email_address', 'Contact address cannot be an UCC address.')
+		except:
+			pass
+		super().clean();
+
+	def save(self, commit=True):
+		# get the Member model instance (ie. a record in the Members table) based on submitted form data
+		m = super().save(commit=False)
+		if (m.display_name == ""):
+			m.display_name = "%s %s" % (m.first_name, m.last_name);
+		# must save otherwise membership creation will fail
+		m.save()
+
+		# now create a corresponding Membership (marked as pending / not accepted, mostly default values)
+		ms = make_pending_membership(m)
+
+		if (commit):
+			ms.save();
+		return m, ms
+
+class RegisterForm(RegisterRenewForm):
+	username = forms.CharField(
+		label='Preferred Username (optional)',
+		required=False,
+		help_text="This will be the username you use to access club systems. You may leave this blank to choose a username later"
+	)
+
+	class Meta():
+		model = Member
+		fields = ['first_name', 'last_name', 'username', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']
+
+
+	def clean(self):
+		try:
+			if (self['email_address'].value() != self['confirm_email'].value()):
+				self.add_error('email_address', 'Email addresses must match.')
+			if (self['email_address'].value().split('@')[1] in ["ucc.asn.au", "ucc.gu.uwa.edu.au"]):
+					self.add_error('email_address', 'Contact address cannot be an UCC address.')
+		except:
+			pass
+		super().clean();
+
+
+class RenewForm(RegisterRenewForm):
+	confirm_email = None
+	membership_type = forms.ChoiceField(label='Select your membership type', required=True, choices=get_membership_choices(is_renew=True))
+
+	class Meta:
+		model = Member
+		fields = ['first_name', 'last_name', 'phone_number', 'is_student', 'is_guild', 'id_number', 'id_desc', 'email_address']
+		exclude = ['username']
+
+	def save(self, commit=True):
+		m, ms = super().save(commit=False)
+		m.username = self.request.user.username
+		m.has_account = m.get_uid() != None
+		if (commit):
+			m.save()
+			ms.save()
+		return m, ms
 
 """
 simple FormView which displays registration form and handles template rendering & form submission
 """
 class RegisterView(MyUpdateView):
-    template_name = 'register.html'
-    form_class = RegisterForm
-    model = Member
-    can_create = False
-
-    """
-    called when valid form data has been POSTed
-    invalid form data simply redisplays the form with validation errors
-    """
-    def form_valid(self, form):
-        # save the member data and get the Member instance
-        m, ms = form.save()
-        messages.success(self.request, 'Your registration has been submitted.')
-
-        # don't set the member session info - user can click on the link
-        #self.request.session['member_id'] = m.id
-        return thanks_view(self.request, m, ms)
+	template_name = 'register.html'
+	form_class = RegisterForm
+	model = Member
+	can_create = False
+
+	"""
+	called when valid form data has been POSTed
+	invalid form data simply redisplays the form with validation errors
+	"""
+	def form_valid(self, form):
+		# save the member data and get the Member instance
+		m, ms = form.save()
+		messages.success(self.request, 'Your registration has been submitted.')
+
+		# don't set the member session info - user can click on the link
+		#self.request.session['member_id'] = m.id
+		return thanks_view(self.request, m, ms)
 
 def thanks_view(request, member, ms):
-    """ display a thankyou page after registration is completed """
-    context = {
-        'member': member,
-        'ms': ms,
-        'login_url': reverse('memberdb:login_member', kwargs={'username': member.username, 'member_token': member.login_token}),
-    }
-    return render(request, 'thanks.html', context)
+	""" display a thankyou page after registration is completed """
+	context = {
+		'member': member,
+		'ms': ms,
+		'login_url': reverse('memberdb:login_member', kwargs={'username': member.username, 'member_token': member.login_token}),
+	}
+	return render(request, 'thanks.html', context)
 
 class RenewView(LoginRequiredMixin, MyUpdateView):
-    template_name = 'renew.html'
-    form_class = RenewForm
-    model = Member
-
-    def get_object(self):
-        u = self.request.user
-
-        obj = Member.objects.filter(username__exact=u.username).first()
-        if (obj is None):
-            # make a new Member object and prefill some data
-            obj = Member(username=u.username)
-            obj.first_name = u.first_name
-            obj.last_name = u.last_name
-            obj.email_address = u.email
-            obj.login_token = None # renewing members won't need this
-        return obj
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context.update({
-            'is_new': Member.objects.filter(username__exact=self.request.user.username).count() == 0,
-        })
-        return context
-
-    def form_valid(self, form):
-        m, ms = form.save()
-        messages.success(self.request, 'Your membership renewal has been submitted.')
-        return HttpResponseRedirect(reverse("memberdb:home"))
+	template_name = 'renew.html'
+	form_class = RenewForm
+	model = Member
+
+	def get_object(self):
+		u = self.request.user
+
+		obj = Member.objects.filter(username__exact=u.username).first()
+		if (obj is None):
+			# make a new Member object and prefill some data
+			obj = Member(username=u.username)
+			obj.first_name = u.first_name
+			obj.last_name = u.last_name
+			obj.email_address = u.email
+			obj.login_token = None # renewing members won't need this
+		return obj
+
+	def get_context_data(self, **kwargs):
+		context = super().get_context_data(**kwargs)
+		context.update({
+			'is_new': Member.objects.filter(username__exact=self.request.user.username).count() == 0,
+		})
+		return context
+
+	def form_valid(self, form):
+		m, ms = form.save()
+		messages.success(self.request, 'Your membership renewal has been submitted.')
+		return HttpResponseRedirect(reverse("memberdb:home"))
diff --git a/src/memberdb/root_actions.py b/src/memberdb/root_actions.py
index f822c827c42a44cb4bf4669db34fd37f3d19fef2..4c6089e86f5dbbbc9a0d68704088b607a752c92a 100644
--- a/src/memberdb/root_actions.py
+++ b/src/memberdb/root_actions.py
@@ -2,22 +2,31 @@ import sys
 import os
 import shutil
 import subprocess
-## WARNING ##
-# this script runs with elevated permissions #
+
+
+   ###     ######  ##     ## ######## ##     ## ##    ##  ######   
+  ## ##   ##    ## ##     ##    ##    ##     ## ###   ## ##    ##  
+ ##   ##  ##       ##     ##    ##    ##     ## ####  ## ##        
+##     ## ##       #########    ##    ##     ## ## ## ## ##   #### 
+######### ##       ##     ##    ##    ##     ## ##  #### ##    ##  
+##     ## ##    ## ##     ##    ##    ##     ## ##   ### ##    ##  
+##     ##  ######  ##     ##    ##     #######  ##    ##  ######   
+
+		# this script runs with elevated permissions #
+			# be very careful with what you do #
 
 def main():
 
 	os.umask(0o077)
 
-	if len(sys.argv) != 2:
-		return 1
-	user = sys.argv[0]
-	mail = sys.argv[1]
+	if len(sys.argv) != 3:
+		exit(1)
+	user = sys.argv[1]
+	mail = sys.argv[2]
 
 	# abort if user does not exist
 	if subprocess.call(["id", user], stderr=subprocess.DEVNULL) != 0:
-		return 1
-
+		exit(1)
 
 	homes = {
 		('/home/ucc/%s' % user, '/home/wheel/bin/skel/ucc'),
@@ -34,7 +43,7 @@ def main():
 		os.system('chmod a+x %s' % home)
 		os.system('chmod a+rX %s/public-html' % home)
 	except:
-		return 1
+		exit(1)
 
 	# write .forward
 	try:
@@ -46,10 +55,12 @@ def main():
 			shutil.chown(forward,user,"gumby")
 			os.chmod(forward, 0o644)
 	except:
-		return 1
+		exit(1)
+
 
 if __name__ == "__main__":
 	main()
+	exit(0)
 
 
 
diff --git a/src/squarepay/dispense.py b/src/squarepay/dispense.py
index abd5a32312d371eb0ab3b361c219f41405576670..e32393578c39716e0fbff21c9ba9254b37a9caaa 100644
--- a/src/squarepay/dispense.py
+++ b/src/squarepay/dispense.py
@@ -55,7 +55,6 @@ def set_dispense_flag(user, flag, reason):
 		log.warning("DISPENSE_BIN is not defined, user will not be disabled")
 		return False
 
-	cmd = [DISPENSE_BIN] + args
 	out = run_dispense('user', 'type', user, flag, reason)
 	s = out.split()
 	if s[2] != "updated":
@@ -63,3 +62,23 @@ def set_dispense_flag(user, flag, reason):
 		log.warning("set_dispense_flag: user was not updated with error: " + out)
 		return False;
 	return True;
+
+def make_dispense_account(user, pin):
+	if DISPENSE_BIN is None:
+		log.warning("DISPENSE_BIN is not defined")
+		return False
+
+	cmdargs = [
+		("user","add", user),
+		("acct",user,"+500","treasurer: new user"),
+		("-u", user, "pinset", pin)
+	]
+
+
+	for args in cmdargs:
+		cmd = [DISPENSE_BIN] + args
+		out = run_dispense('user', 'type', user, flag, reason)
+		if out == None:
+			raise CalledProcessError
+
+	return True;
diff --git a/src/templates/admin/memberdb/account_create.html b/src/templates/admin/memberdb/account_create.html
index 0f76d5153c02d8a373a3863348279c05a8293ee6..cebe02f1209314d1045efb52c0f73f3d8485ee6e 100644
--- a/src/templates/admin/memberdb/account_create.html
+++ b/src/templates/admin/memberdb/account_create.html
@@ -44,8 +44,8 @@
 	</fieldset>
 	<div class="submit-row">
 	  {% if wizard.steps.prev %}
-		<button name="wizard_goto_step" class="button" type="submit" value="{{ wizard.steps.prev }}"> prev </button>
-	 {% endif %}
+	    <button name="wizard_goto_step" class="button" type="submit" value="{{ wizard.steps.prev }}"> prev </button>
+	  {% endif %}
 	  
 	{% if wizard.steps.next %}
 		<input type="submit" value="{% trans "next" %}"/>
diff --git a/src/templates/admin/memberdb/membership_actions.html b/src/templates/admin/memberdb/membership_actions.html
index ce12e156bda0e7749ef0d39781dacf4def36a385..8bced93e869e7e28a0dc950bfff6e72455cd54a6 100644
--- a/src/templates/admin/memberdb/membership_actions.html
+++ b/src/templates/admin/memberdb/membership_actions.html
@@ -1,8 +1,10 @@
 {% load static %}{# this template is used to generate the member action buttons, see memberdb/admin.py #}
 <div class="member-actions">
-    <a class="button" href="{{ member_url }}">Edit</a>&nbsp;
-    {% if not ms.approved %}
-    <a class="button" href="{{ member_approve }}">Approve</a>&nbsp;
-    {% endif %}
-    <a class="button" href="{{ create_account }}">Create Account</a>&nbsp;
+	<a class="button" href="{{ member_url }}">Edit</a>&nbsp;
+	{% if not ms.approved %}
+	<a class="button" href="{{ member_approve }}">Approve</a>&nbsp;
+	{% endif %}
+	{% if not member.has_account %}
+	<a class="button" href="{{ create_account }}">Create Account</a>&nbsp;
+	{% endif %}
 </div>
diff --git a/src/templates/membership_summary.html b/src/templates/membership_summary.html
index aeffa35b3f30715546aab9fd453ebb67de50e41e..29d69251a8f0afc62df4c2cdd54132c969a19dd2 100644
--- a/src/templates/membership_summary.html
+++ b/src/templates/membership_summary.html
@@ -19,7 +19,7 @@
 
     {% block email %}
     <tr class="{% cycle rcl %}">
-        <th>Email</th>
+        <th>Contact email</th>
         <td>
         {% if member.email_address %}
             <a href="mailto:{{ member.email_address }}">{{ member.email_address }}</a>
@@ -47,9 +47,13 @@
         <td>{% if member.is_guild %}<img src="{% static 'admin/img/icon-yes.svg' %}" alt="yes">{% else %}<img src="{% static 'admin/img/icon-no.svg' %}" alt="no">{% endif %}</td>
     </tr>
     <tr class="{% cycle rcl %}">
-        <th>Student email / Drivers license</th>
+        <th>Student number or Other ID</th>
         <td>{% if member.id_number %}{{ member.id_number }}{% else %}<i>not provided</i>{% endif %}</td>
     </tr>
+    <tr class="{% cycle rcl %}">
+        <th>ID type</th>
+        <td>{% if member.id_desc %}{{ member.id_desc }}{% else %}<i>not provided</i>{% endif %}</td>
+    </tr>
     {% endblock %}
 </table>
 {% endblock %}