-1

I am having issue placing order on Biannce using API. I can get balance with this signature - works fine.

Placing order giving me: { code: -1022, msg: 'Signature for this request is not valid.' }

Have no idea what is wrong - any idea of what I am doing wrong?

Here is my code:

const axios = require('axios');
const crypto = require('crypto');
const API_KEY = 'xx';
const API_SECRET = 'xx';
const BASE_URL = 'https://fapi.binance.com';

const signature = (data) => {
    return crypto.createHmac('sha256', API_SECRET).update(data).digest('hex');
};

const createRequestConfig = (method, endpoint, data = {}) => {
    const timestamp = Date.now();
    data.timestamp = timestamp;

    const signatureData = Object.keys(data)
        .sort()
        .map(key => `${key}=${data[key]}`)
        .join('&');

    const signatureString = `${signatureData}&timestamp=${timestamp}`;

    const config = {
        method: method,
        url: `${BASE_URL}${endpoint}?${signatureString}&signature=${signature(signatureString)}`,
        headers: {
            'X-MBX-APIKEY': API_KEY
        }
    };

    if (method === 'POST') {
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
        config.data = signatureData + `&timestamp=${timestamp}&signature=${signature(signatureString)}`;
    }

    return config;
};

const placeMarketOrder = async (symbol, side, notionalValue) => {
    const endpoint = '/fapi/v1/order';
    const data = {
        symbol: symbol,
        side: side,
        type: 'MARKET',
        quantity: 0, // Placeholder, will be calculated later
        newOrderRespType: 'FULL', // Return detailed order response
        timestamp: Date.now()
    };

    const config = createRequestConfig('POST', endpoint, data);

    try {
        const response = await axios(config);

        // Calculate quantity based on provided notionalValue and executed quantity
        const executedQty = response.data.executedQty;
        const calculatedQuantity = executedQty / notionalValue;

        console.log('Order response:', response.data);
        console.log('Calculated quantity:', calculatedQuantity);
    } catch (error) {
        console.error('Error placing order:', error.response.data);
    }
};
mch_dk
  • 369
  • 1
  • 4
  • 15

1 Answers1

0

Have you tried sending with application/json content type?

'content-type': 'application/json',
Accept: 'application/json',

And now to the point of potential failure - I have no idea what you end up sending as symbol - but a safer way is to URI encode the string when sending. Try this method for making the queryString (it is written in TS, so you may have to remove that if your stack doesn't support it):

export const makeQueryString = (q: any, noEncode: boolean = false) => {
  return Object.keys(q)
    .sort()
    .reduce((a, k) => {
      if (Array.isArray(q[k])) {
        q[k].forEach((v) => {
          a.push(k + '=' + (noEncode ? v : encodeURIComponent(v)));
        });
      } else if (q[k] !== undefined) {
        a.push(k + '=' + (noEncode ? q[k] : encodeURIComponent(q[k])));
      }
      return a;
    }, [])
    .join('&');
};

Another potential point of failure I heard tell of is that the timestamp must come at the very end of the querystring (and of course the signature must be built accordingly). I see that you are doing that already :)

Lior Kupers
  • 528
  • 6
  • 18