PPS: with the following script you can even get a list of the residents who used your vendor, to find out how many unique "purchases" were made or to have a look at some profiles of your target group:
string item_name = "SUN T-shirt"; // change the text within the quotes
string message = "Have fun with your new T-Shirt! You can find it in the Clothes folder of your inventory.";
integer show_message = TRUE; // set to false if the message should not be shown
string hovering_text = "Click me for a free T-Shirt!"; // change if needed
list name_list;
integer counter=0;
default
{
state_entry()
{
llSetText(hovering_text,<1,1,1>,1);
llListen(0,"",llGetOwner(),"");
}
touch_start(integer total_number)
{
string name=llDetectedName(0);
name_list+=name;
llGiveInventory(llDetectedKey(0),item_name);
++counter;
if (show_message==TRUE) llWhisper(0,message);
}
listen(integer chan, string name, key id, string mes)
{
if (mes=="counter report")
llWhisper(0,"Handed out "+(string)counter+" copies of '"+item_name+"'.");
else if (mes=="vendor report")
{
llWhisper(0,"Handed out "+(string)counter+" copies of '"+item_name+"' to the following persons:");
integer length = llGetListLength(name_list);
integer i;
for (i=0;i < length;++i)
{
llWhisper(0,llList2String(name_list,i));
}
}
else if (mes=="reset counter")
{
counter=0;
name_list=[""];
llWhisper(0,"Counter for item '"+item_name+"' has been reset to 0.");
}
}
}
The chat command "vendor report" now reads the name list in addition to the counter value, while "counter report" only tells you the current counter.
For more privacy, you could use this script, which reports to you only (chat commands & output aren't shown in the public chat channel; the chat commands are now "/1 vendor report", "/1 counter report" and "/1 counter reset"

:
string item_name = "SUN T-shirt"; // change the text within the quotes
string message = "Have fun with your new T-Shirt! You can find it in the Clothes folder of your inventory.";
integer show_message = TRUE; // set to false if the message should not be shown
string hovering_text = "Click me for a free T-Shirt!"; // change if needed
list name_list;
integer counter=0;
default
{
state_entry()
{
llSetText(hovering_text,<1,1,1>,1);
llListen(1,"",llGetOwner(),"");
}
touch_start(integer total_number)
{
string name=llDetectedName(0);
name_list+=name;
llGiveInventory(llDetectedKey(0),item_name);
++counter;
if (show_message==TRUE) llWhisper(0,message);
}
listen(integer chan, string name, key id, string mes)
{
if (mes=="counter report")
llOwnerSay("Handed out "+(string)counter+" copies of '"+item_name+"'.");
else if (mes=="vendor report")
{
llOwnerSay("Handed out "+(string)counter+" copies of '"+item_name+"' to the following persons:");
integer length = llGetListLength(name_list);
integer i;
for (i=0;i < length;++i)
{
llOwnerSay(llList2String(name_list,i));
}
}
else if (mes=="reset counter")
{
counter=0;
name_list=[""];
llOwnerSay("Counter for item '"+item_name+"' has been reset to 0.");
}
}
}
/Edit: you only need one of those scripts, of course

depending on which functions you need.
Ishtara (bored and in scripting mood this morning)