Pretty much any character can be used, including '-' and '.', If the serial number remains unique. Special characters, such as "\", must be properly escaped, although they may not be compatible with your database or may cause other problems if they are not handled properly elsewhere in your code.
I just tried the pass with the following serial number and it was added to the Passbook without any problems.
"serialNumber":"[]{}-_)(*&^%$#@!`~+=|\\\/?.><,:;"
UTF8 encoded characters are also beautiful:
"serialNumber":"\u9127\u6a02\u611a"
As for the maximum length, I do not know any restrictions, although it would be quite simple to experiment.
This 400-character series is also swallowing.
"serialNumber":"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
I would recommend not using any user input for the serial interface, as this can lead to non-unique collisions and open you up to injection attacks. Also complying with XML standards is not a bad practice to avoid any problems if you change your architecture (say, for a web services solution like AWS DynamoDB) in-line. Base64 encoding your serial number will provide wide compatibility.
A serial number can also be used to store metadata in the aisle, for example.
"serialNumber":"UniqueID|data1|data2|data3|etc."
source share