it works when i use a java or php code
For testing only, change both the perl code and the java/php code to use a known nonce instead of a random one. Then compare the signatures you get from both perl and java/php for the same JSON request. If they differ, compare how you create them in both. Alter the perl code until they match. Then test with the API. Once that works switch the nonces back to random.
FWIW, there are enough tried and tested URL encoding functions on CPAN that I would not bother to write my own. YMMV.