BatchOrder invalid signature error

Hi, I’m getting invalid signature error for batchOrders: {'code': -1022, 'msg': 'Signature for this request is not valid.'}

The code below works for regular orders, and I’m not sure why it doesn’t work for batch. Any help is appreciated:

def sign(query_string):
        return hmac.new(secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

def finalizeBatch(payload):
        payload['timestamp'] = int(time.time() * 1000)
        params = urlencode(payload)
        payload['signature'] = sign(params)
        return payload

def send(payload):
        payload = finalizeBatch(payload)
        return requests.post(f"{url}/fapi/v1/batchOrders",  params=payload,  headers={'X-MBX-APIKEY' : key})

This is the payload that is passed to the finalizeBatch function

{
   "batchOrders":[
      {
         "symbol":"BTCUSDT",
         "side":"BUY",
         "quantity":0.1,
         "timeInForce":"GTC",
         "type":"LIMIT",
         "price":29998,
         "reduceOnly":false
      },
      {
         "symbol":"BTCUSDT",
         "side":"SELL",
         "quantity":0.1,
         "timeInForce":"GTC",
         "type":"STOP",
         "price":29992.0,
         "reduceOnly":true,
         "stopPrice":29994.0
      }
   ],
   "timestamp":1649466929400
}

When you sign your requests, you should be clear what do you actually send to the server.
The [requests.post] may urlencode some special characters in your payload so you should make the query_string right before you sign it.

You can try codes below:

def sign(query_string):
        return hmac.new(secret.encode(), query_string.replace('"','%22').replace('{','%7B').replace('}','%7D').encode(), hashlib.sha256).hexdigest()

Try this.

def getSignature(self, params={}):
        secret = os.getenv("BINANCE_SECRET")
        if params:
            params["timestamp"] = self.timeStamp
            params = urlencode(params)
        else:
            params = urlencode({"timestamp": self.timeStamp,})

        hashedsig = hmac.new(secret.encode("utf-8"), params.encode("utf-8"), 
        hashlib.sha256).hexdigest()

        signature = {"timestamp": self.timeStamp,"signature": hashedsig,}

        return signature

    def requestPost(url, params, signature):
        params.update(signature)
        r = requests.post(url="https://testnet.binancefuture.com/" + url, headers=headers, 
        data=params)
        response = r.json()
        return response




orderData=[{...},{...},{...}]
payload= {"batchOrders": json.dumps(orderData)}
endPoint = "/fapi/v1/batchOrders"
orderResp = requestPost(endPoint, params, getSignature(params))