A byte is nothing more than an another name for unsigned char; no idea where your comment about C++ and bytes came from. If needed you can cast.
No idea about MQTT, but what I would do is try something like
void callback(const char topic, byte* payload, unsigned int length)
for(int cnt=0;cnt<length; cnt++)
This will print the hex values for whatever you receive; see e.g. asciitable.com. For your example you will see at least
30 32 3A 30
It’s important to check if there is anything else after that like 0D and / or 0A (carriage return and / or linefeed).
Let’s say that your received (note that leading zeroes are omitted by serial.print)
30 32 3A 30 A D
You can copy the bytes to a character array; you might be able to work on the payload variable directly, not sure.
// character array with space for 6 characters and terminating nul character
// make sure it's big enough to hold the longest message
// clear the data
memset(data, 0, sizeof(data));
// copy payload to data
memcpy(data, payload, length);
You now have a so-called C string (nul terminated character array) and can process that. Below a small function to strip carriage returns and/or linefeeds
trim CR and LF from end of text
In: pointer to text to trim
Returns: pointer to (trimmed) text
this modifies the original text
char *trim(char *txt)
while (txt[strlen(txt) - 1] == '\r' ||
txt[strlen(txt) - 1] == '\n')
txt[strlen(txt) - 1] = '\0';
You can call this after the memcpy and use e.g. strtok() or strchr() to split the received text on the colon.
If you can work directly on the payload and there is a carriage return or linefeed, you can replace them by a nul terminator and directly use strtok() or strchr() on the payload. You might have to use a cast (not sure).
As said, no experience with MQTT so not sure which way one should go.