diff --git a/components/susignup-admin.php b/components/susignup-admin.php
index 4b287169deb17d1363f96a833a72bfdd8b7b27ee..eb27cfedebbd3ba1faf12f43bda161b64081dd89 100644
--- a/components/susignup-admin.php
+++ b/components/susignup-admin.php
@@ -7,6 +7,7 @@
  ***/
 
 include("../lib/member_functions.php");
+include("../lib/date.php");
 include("../suapi.inc.php");
 
 //Restrict access to staff. 
@@ -147,22 +148,164 @@ if (isset($session->groups[$permission])) {
 				}
 			}
 		}
+	} else if ($mode=="renew") {
+		if (empty($_REQUEST['member'])){
+			$mode='error';
+			$smarty->assign('error_text',"Can't renew a member without knowing their username!");
+		} else if (!isset($_REQUEST['renewconf'])) {
+			//Should be trying to renew $_REQUEST['member']
+			$username=urldecode($_REQUEST['member']);
+			$q = "SELECT username, typename, sid, paid, email FROM members, member_type WHERE username=?";
+			$res = $sucsDB->Execute($q,array($username));
+			if (!$res) {
+				$mode='error';
+				$smarty->assign('error_text', "A database error occurred while trying to retrieve member details");
+			} else if ($res->fields['paid'] == paidUntil(time())) {
+					$mode='error';
+					$smarty->assign('error_text', 'User appears to have been renewed already?');
+			} else {
+				$smarty->assign('renew_user', $username);
+				$smarty->assign('renew_paid', $res->fields['paid']);
+				$smarty->assign('renew_type', $res->fields['typename']);
+				$url = "https://$suapi_user:$suapi_pass@hap.swansea-union.co.uk/memberships/Membership.asmx/IsPersonMember?strCriteria=".$res->fields['sid']."&GroupingId=6613";
+                                $apiReq = curl_init();
+                                curl_setopt($apiReq, CURLOPT_URL, $url);
+                                curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);
+
+                                $apiResult = curl_exec($apiReq);
+				$xml=new SimpleXMLElement($apiResult);
+				$ismember = $xml[0];
+
+				$user = posix_getpwnam($session->username);
+
+				if ($ismember!="true") {
+					$mode='error';
+					$smarty->assign('error_text', 'Member does not appear to have paid via the SU system. Use the old renewals system if they have paid using some other method');;
+				} else {
+					if (renew_member($username, $user['uid'], $user['name'])) {
+						message_flash("Successfully renewed");
+						$mode='menu';
+					} else {
+						$mode='error';
+						$smarty->assign('error_text', 'An error occurred renewing account '.$username);
+					}
+
+				}
+
+			}
+
+		}
+			
+	} else if ($mode == 'renewals') {
+		//Get list of members according to the SU
+		$url = "https://$suapi_user:$suapi_pass@hap.swansea-union.co.uk/memberships/Membership.asmx/GetMemberListData?GroupingId=6613";
+		$apiReq = curl_init();
+		curl_setopt($apiReq, CURLOPT_URL, $url);
+		curl_setopt($apiReq, CURLOPT_RETURNTRANSFER, TRUE);
+
+		$apiResult = curl_exec($apiReq);
+		$sumembers = su_response_decode($apiResult);
+		$matches = array();
+		foreach ($sumembers as $sumem) {
+			$sucsmem = get_sucs_record($sumem['uni_card_number']);
+			if ($sucsmem && $sucsmem['paid'] != paidUntil(time()) && $sucsmem['type']==1) {
+				$matches[]=array($sumem['firstName']." ".$sumem['lastName'], $sucsmem['realname'], $sumem['uni_card_number'], $sucsmem['username'], $sucsmem['paid']);
+			}
+		}
+		$smarty->assign("matches", $matches);
+	} else if ($mode == 'renewals2') {
+		$failures = array();
+		$successes = array();
+
+		if (empty($_REQUEST['renew'])) {
+			$mode='error';
+			$smarty->assign("error_text", "Can't renew an empty list!");
+		} else {
+			foreach($_REQUEST['renew'] as $user) {
+				$admin_user=posix_getpwnam($session->username);
+				if (renew_member($user, $admin_user['uid'], $admin_user['name'])) {
+					$successes[]=$user;
+				} else {
+					$failures[]=$user;
+				}
+			}
+			$smarty->assign("attempt", count($_REQUEST['renew']));
+			$smarty->assign("failures", count($failures));
+			$smarty->assign("failusers", $failures);
+			$smarty->assign("successes", count($successes));
+		}
 	}
 }
+
+
+$smarty->assign('renewables', get_renewable_members());
 $smarty->assign('title', 'SU Signup Admin');
 $smarty->assign('mode', $mode);
 $body = $smarty->fetch("susignup-admin.tpl");
 $smarty->assign('body', $body);
 $smarty->assign("extra_styles", array("$baseurl/css/susignup-admin.css"));
 
-function su_json_decode($text) {
-	$re1='.*?';
-	$re2='(\\{.*?\\})';
-	if ($c=preg_match_all ("/".$re1.$re2."/is", $text, $matches))
-	{
-		$json_string=$matches[1][0];
-	}else{
-		  return FALSE;
-	}
-	return json_decode($json_string,TRUE);
+function su_response_decode($text) {
+	$x = new SimpleXMLElement($text);
+	return json_decode($x[0],TRUE);
 } 
+
+function get_sucs_record($sid) {
+	global $sucsDB;
+
+	$query = "SELECT * FROM members WHERE sid=?;";
+	$res  = $sucsDB->Execute($query, array($sid));
+	if (!$res || $res->RecordCount()>1) {
+		return FALSE;
+	}
+        return $res->FetchRow();	
+}
+
+function get_renewable_members() {
+	global $sucsDB;
+	$q = "SELECT username, username||' ('||realname||')' AS display FROM members, member_type WHERE paid != ? AND type=1 AND type=member_type.id ORDER BY paid;";
+	$r = $sucsDB->Execute($q, array(paidUntil(time())));
+	if(!$r) {
+		return FALSE;
+	}
+	$retvals = array();
+	while ($rec=$r->FetchRow()) {
+		$retvals[$rec['username']]=$rec['display'];
+	}
+	return $retvals;
+}
+
+function renew_member($renew_name, $admin_uid, $admin_name) {
+	global $sucsDB;
+
+	$q="UPDATE members SET paid=?, lastupdate=DEFAULT, lastedit=? WHERE username=?;";
+	$r=$sucsDB->Execute($q, array(paidUntil(time()), $admin_uid, $renew_name));
+	if (!$r) {
+		print $sucsDB->ErrorMsg();
+		return FALSE;
+	} else {	
+		$q="SELECT email, typename FROM members, member_type WHERE username=?  AND type=member_type.id;";
+		$r=$sucsDB->Execute($q, array($renew_name));
+
+		$message  = "Account Renewal notification\n\n";
+		$message .= "Account   : ".$renew_name."\n";
+		$message .= "User Type : ".$r->fields['typename']."\n";
+		$message .= "Renewed by: ".$admin_name."\n\n";
+		$message .= "**** Payment was made via the SU payments system ****\n";
+		$message .= "Regards\n  The SU Renewals script";
+		mail("treasurer@sucs.org","Account Renewal",$message);
+		
+		$message = "Your Swansea University Computer Society (SUCS) membership has been renewed\n\n";
+		$message .= "Username: ".$renew_name."\n";
+		$message .= "If you do not know or have forgotten your password, please email admin@sucs.org to arrange for it to be changed.\n\n";
+		$message .= "Regards\n  The SUCS admin";
+		$header = "From: admin@sucs.org\r\n";
+		$header .= "Reply-To: admin@sucs.org";
+		// Personal account
+		mail($r->fields['email'],"SUCS account renewal",$message,$header);
+		// sucs account
+		mail($renew_name."@sucs.org","SUCS account renewal",$message,$header);
+		return TRUE;
+	}
+
+}
diff --git a/htdocs/css/susignup-admin.css b/htdocs/css/susignup-admin.css
new file mode 100644
index 0000000000000000000000000000000000000000..8cd0251a9941eaab9b42bfcd7c09f447abf3787d
--- /dev/null
+++ b/htdocs/css/susignup-admin.css
@@ -0,0 +1,48 @@
+div.susignup-admin-menu {
+	float: left;
+	width: 30%;
+	margin-left: 10px;
+	background: #E76808;
+	border-radius: 15px;
+	border-radius: 15px;
+	-moz-border-radius: 15px;
+	-moz-border-radius: 15px;
+}
+
+div.susignup-admin-menu select {
+	position: relative;
+	width: 65%;
+}
+
+div.susignup-admin-menu label {
+	position: relative;
+	width: 9em;
+}
+
+div.susignup-admin-menu input#rnsubmit {
+	position: relative;
+	width: 70px;
+}
+
+#susignup-renewals {
+	width: 90%;
+	border: 2px ridge;
+	border-collapse: collapse;
+}
+
+#susignup-renewals td {
+	border: 2px ridge;
+	padding-left: 4px;
+	padding-right: 2px;
+}
+
+#susignup-renewals th {
+	border: 2px ridge;
+	text-align: center;
+	padding-left: 2px;
+	padding-right: 2px;
+}
+
+.centre{
+	text-align: center;
+}
diff --git a/templates/susignup-admin.tpl b/templates/susignup-admin.tpl
index ccc1791ae917a90cfb329984e68d3aa9b8c5d4f4..49a0b2b3e0a5e908dd6e042c6bc130b7ac17e28e 100644
--- a/templates/susignup-admin.tpl
+++ b/templates/susignup-admin.tpl
@@ -4,14 +4,44 @@
 		<strong>Error: </strong> {$error_text}
 	</div>
  {/if}
- {if $mode == 'renew'}
-	<div class='errorbar'>
-		<strong>Error: </strong> Not implemented yet
-	</div>
- {elseif $mode == 'renewals'}
-	<div class='errorbar'>
-		<strong>Error: </strong> Not implemented yet
-	</div>
+ {if $mode == 'renewals'}
+<form action='{$componentpath}' method='post'>
+ <table id='susignup-renewals'>
+	<thead>
+		<tr><th>Renew Now?</th><th>Name (SU)</th><th>Name (SUCS)</th><th>Student ID</th><th>SUCS Username</th><th>Paid Until</th></tr>
+	</thead>
+	<tbody>
+{foreach from=$matches item=match}
+		<tr><td class='centre'><input name='renew[]' id='renew' value='{$match[3]}' type='checkbox' checked='checked'/></td><td>{$match[0]}</td><td>{$match[1]}</td><td class='centre'>{$match[2]}</td><td>{$match[3]}</td><td class='centre'>{$match[4]}</td></tr>
+{foreachelse}
+		<tr><td colspan='6'><em>No matches found</em></td></tr>
+{/foreach}
+	</tbody>
+	<tfoot>
+		<tr><td colspan='5'><strong>For large numbers of renewals, this can take a while!</strong></td><td class='centre'><input type='submit' name='rwsubmit' id='rwsubmit' value='Go!' /></td></tr>
+	</tfoot>
+</table>
+<input type='hidden' name='mode' id='mode' value='renewals2' />
+</form>
+ {elseif $mode == 'renewals2'}
+<div class='centre'>
+<div class='cbb' style='text-align: left'>
+<h3> Mass renewal results </h3>
+<strong>{$attempt}</strong> accounts marked for renewal<br />
+<hr />
+{if $successes == $attempt}
+<strong>All</strong> of these requests were successful.<br />
+{else}
+<strong>{$successes}</strong> requests were successful, and <span style='color: red'><strong>{$failures}</strong></span> requests failed.<br />
+The following accounts failed to renew:
+<ul>
+{foreach from=$failusers item=f}
+<li>{$f}</li>
+{/foreach}
+</ul>
+{/if}
+</div>
+</div>
  {elseif $mode == 'search'}
 <div style='text-align: center'>
  <div class='cbb' style='text-align: left'>
@@ -26,7 +56,7 @@
 	</form>
  </div>
 </div>
- {elseif $mode == 'menu' || $mode == 'error'} 
+ {elseif $mode == 'menu' || $mode == 'error' || $mode == 'renew'} 
 	<p>
 This component allows staff members to sort out memberships and renewals that have been paid for via the SU payments system. </p>
 <p>Renew an individual member, generate a list of members that look like they've paid via the SU system or begin the signup process for a newbie who doesn't have their transaction ID by selecting the appropriate option below.
@@ -34,12 +64,20 @@ This component allows staff members to sort out memberships and renewals that ha
 <div style='text-align: center'>
 <div class='susignup-admin-menu cbb'>
 <h3>Renew existing account:</h3>
-Username selector
-Submit Button
+<form action='{$componentpath}' method='post'>
+	<label for='member'>Account:</label>
+	{html_options name=member options=$renewables}
+	<input type='hidden' name='mode' id='mode' value="renew" />
+	<input type='submit' name='rnsubmit' id='rnsubmit' value="Renew" />
+</form>
 </div>
 <div class='susignup-admin-menu cbb'> 
-<h3>Suggest probable renewals</h3>
-Submit Button
+<h3>Bulk Renewals</h3>
+<p style='text-align: left'>This will query the SU API for all current SUCS members and generate a list of corresponding SUCS accounts to be renewed.<br /> This process can take a little while to run</p><br />
+<form action='{$componentpath}' method='post'>
+	<input type='submit' name='rwsubmit' id='rwsubmit' value='Generate List' />
+	<input type='hidden' name='mode' id='mode' value='renewals' />
+</form>
 </div>
 <div class='susignup-admin-menu cbb'>
 <h3>Signup a newbie</h3>