Hex colors are made up of 6 hexadecimal digits. The first two digits are for the red shade, the second two are for the green, and the last two are for the blue. Within the shades, 00 is the absence of color and FF is the highest value for the color. So, #FF0000 would be bright red with no green or blue, and #00CCFF would be very blue and a little green with no red at all.
The example colors you give actually have a different makeup of red, green, and blue. #66CC00 is mostly green with some red while #99FFCC is mostly green with some blue and red.
You should break your colors into their red, green, and blue components before converting them to decimal, average the two, and then convert back:
#66 CC 00 -> 102 204 0
#99 FF CC -> 153 255 204
Average between the two: 128 230 102: #80E666
After finding the in-between color, you can approximate the closest web safe color: #99FF66
A converter between hexadecimal and decimal to do this yourself can be found here.
Here is a PHP script that does what you need. Here is a JavaScript script based off of the method described above (related hex to decimal conversion in JS):
color1 = "#66CC00";
color2 = "#99FFCC";
r1 = parseInt(color1.substring(1,3), 16);
g1 = parseInt(color1.substring(3,5), 16);
b1 = parseInt(color1.substring(5,7), 16);
r2 = parseInt(color2.substring(1,3), 16);
g2 = parseInt(color2.substring(3,5), 16);
b2 = parseInt(color2.substring(5,7), 16);
r3 = (Math.round((r1 + r2)/2)).toString(16);
g3 = (Math.round((g1 + g2)/2)).toString(16);
b3 = (Math.round((b1 + b2)/2)).toString(16);
color3 = "#" + r3 + g3 + b3;