diff --git a/src/server/common.h b/src/server/common.h
index 34361b950f97c0e0a1457c04ff720f3fa1df2548..cf68523908971885c50e3f79af26c79790ad4205 100644
--- a/src/server/common.h
+++ b/src/server/common.h
@@ -81,6 +81,7 @@ extern char	*mkstr(const char *Format, ...);
 
 // --- Dispense ---
 extern int	DispenseItem(int ActualUser, int User, tItem *Item);
+extern int	DispenseRefund(int ActualUser, int DestUser, tItem *Item, int OverridePrice);
 extern int	DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven);
 extern int	DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven);
 extern int	DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven);
diff --git a/src/server/dispense.c b/src/server/dispense.c
index 23e73afff8f524e284f3c2a7e151659a28a1ed6e..01b53c8338f712c43e54374740fad9fffc83fb6b 100644
--- a/src/server/dispense.c
+++ b/src/server/dispense.c
@@ -73,6 +73,39 @@ int DispenseItem(int ActualUser, int User, tItem *Item)
 	return 0;	// 0: EOK
 }
 
+/**
+ * \brief Refund a dispense
+ */
+int DispenseRefund(int ActualUser, int DestUser, tItem *Item, int OverridePrice)
+{
+	 int	ret;
+	 int	src_acct, price;
+	char	*username, *actualUsername;
+
+	src_acct = Bank_GetAcctByName(COKEBANK_SALES_ACCT);
+
+	if( OverridePrice > 0 )
+		price = OverridePrice;
+	else
+		price = Item->Price;
+
+	ret = _Transfer( src_acct, DestUser, price, "Refund");
+	if(ret)	return ret;
+
+	username = Bank_GetAcctName(DestUser);
+	actualUsername = Bank_GetAcctName(ActualUser);
+	
+	Log_Info("refund '%s' (%s:%i) to %s by %s [cost %i, balance %i]",
+		Item->Name, Item->Handler->Name, Item->ID,
+		username, actualUsername, price, Bank_GetBalance(DestUser)
+		);
+
+	free(username);
+	free(actualUsername);
+
+	return 0;
+}
+
 /**
  * \brief Give money from one user to another
  */
@@ -147,7 +180,7 @@ int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven)
 	char	*dstName, *byName;
 	
 #if DISPENSE_ADD_BELOW_MIN
-//	ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
+	ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
 #else
 	ret = Bank_Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
 #endif
@@ -234,10 +267,10 @@ int _GetMinBalance(int Account)
 	if( flags & USER_FLAG_INTERNAL )	return INT_MIN;
 	
 	// Admin to -$50
-	if( flags & USER_FLAG_ADMIN )	return -5000;
+//	if( flags & USER_FLAG_ADMIN )	return -5000;
 	
 	// Coke to -$20
-	if( flags & USER_FLAG_COKE )	return -2000;
+//	if( flags & USER_FLAG_COKE )	return -2000;
 	
 	// Anyone else, non-negative
 	return 0;
diff --git a/src/server/server.c b/src/server/server.c
index 79a5c2dded88e002e4b2faba608390dcc853fe37..de79f417c79a9530152cf5c3935055bdf977240d 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -60,6 +60,7 @@ void	Server_Cmd_SETEUSER(tClient *Client, char *Args);
 void	Server_Cmd_ENUMITEMS(tClient *Client, char *Args);
 void	Server_Cmd_ITEMINFO(tClient *Client, char *Args);
 void	Server_Cmd_DISPENSE(tClient *Client, char *Args);
+void	Server_Cmd_REFUND(tClient *Client, char *Args);
 void	Server_Cmd_GIVE(tClient *Client, char *Args);
 void	Server_Cmd_DONATE(tClient *Client, char *Args);
 void	Server_Cmd_ADD(tClient *Client, char *Args);
@@ -88,6 +89,7 @@ const struct sClientCommand {
 	{"ENUM_ITEMS", Server_Cmd_ENUMITEMS},
 	{"ITEM_INFO", Server_Cmd_ITEMINFO},
 	{"DISPENSE", Server_Cmd_DISPENSE},
+	{"REFUND", Server_Cmd_REFUND},
 	{"GIVE", Server_Cmd_GIVE},
 	{"DONATE", Server_Cmd_DONATE},
 	{"ADD", Server_Cmd_ADD},
@@ -227,6 +229,7 @@ void Server_Start(void)
 			case 0x825F0D11:	// 130.95.13.17	mermaid
 			case 0x825F0D12:	// 130.95.13.18	mussel
 			case 0x825F0D17:	// 130.95.13.23	martello
+			case 0x825F0D2A:	// 130.95.13.42 meersau
 			case 0x825F0D42:	// 130.95.13.66	heathred
 				bTrusted = 1;
 				break;
@@ -713,6 +716,54 @@ void Server_Cmd_DISPENSE(tClient *Client, char *Args)
 	}
 }
 
+void Server_Cmd_REFUND(tClient *Client, char *Args)
+{
+	tItem	*item;
+	 int	uid, price_override = 0;
+	char	*username, *itemname, *price_str;
+
+	if( Server_int_ParseArgs(0, Args, &username, &itemname, &price_str, NULL) ) {
+		if( !itemname || price_str ) {
+			sendf(Client->Socket, "407 REFUND takes 2 or 3 arguments\n");
+			return ;
+		}
+	}
+
+	if( !Client->bIsAuthed ) {
+		sendf(Client->Socket, "401 Not Authenticated\n");
+		return ;
+	}
+
+	// Check user permissions
+	if( !(Bank_GetFlags(Client->UID) & (USER_FLAG_COKE|USER_FLAG_ADMIN))  ) {
+		sendf(Client->Socket, "403 Not in coke\n");
+		return ;
+	}
+
+	uid = Bank_GetAcctByName(username);
+	if( uid == -1 ) {
+		sendf(Client->Socket, "404 Unknown user\n");
+		return ;
+	}
+	
+	item = _GetItemFromString(itemname);
+	if( !item ) {
+		sendf(Client->Socket, "406 Bad Item ID\n");
+		return ;
+	}
+
+	if( price_str )
+		price_override = atoi(price_str);
+
+	switch( DispenseRefund( Client->UID, uid, item, price_override ) )
+	{
+	case 0:	sendf(Client->Socket, "200 Item Refunded\n");	return ;
+	default:
+		sendf(Client->Socket, "500 Dispense Error\n");
+		return;
+	}
+}
+
 void Server_Cmd_GIVE(tClient *Client, char *Args)
 {
 	char	*recipient, *ammount, *reason;