币安加密货币交易机器人下单遇-1102签名错误及手续费税费处理问题
币安API订单签名错误及手续费逻辑问题
我正在开发一款币安加密货币买卖机器人,当前创建新订单的代码遇到两个问题:
- 签名错误:返回Error -1102,提示“Mandatory parameter 'signature' was not sent, was empty/null, or malformed”
- 手续费逻辑:需要实现币安用用户持有加密货币支付手续费和税费的逻辑,但尝试后仍未解决
之前还遇到过类似的-1102错误(参数'timestamp'未发送等),当前代码如下:
async function novaOrdem(symbol, quantity, side, price) { const type = 'MARKET'; const recvWindow = 5000; const commissionRates = await getCommissionRates(symbol); const commission = side === 'BUY' ? commissionRates.standardCommission.buyer : commissionRates.standardCommission.seller; const tax = side === 'BUY' ? commissionRates.taxCommission.buyer : commissionRates.taxCommission.seller; const discount = commissionRates.discount.discount; const priceWithCommission = price * (1 + parseFloat(commission) + parseFloat(tax) - parseFloat(discount)); const params = { symbol, quantity, side, type, price: priceWithCommission, timestamp: Date.now(), recvWindow }; const queryString = Object.keys(params).map(key => `${key}=${encodeURIComponent(params[key])}`).join('&'); const signature = crypto.createHmac('sha256', CHAVE_SECRETA).update(queryString).digest('hex'); try { const { data } = await axios.post(`${API_URL}/api/v3/order`, null, { params: { ...params, signature }, headers: { 'X-MBX-APIKEY': CHAVE_API } }); console.log(data); } catch (erro) { console.error('Erro ao colocar a ordem:', erro.response.data); } }
问题1:签名错误修复方案
- 移除MARKET订单的price参数:币安API中MARKET类型订单不需要传入price参数,多余参数会导致签名计算不匹配,这是触发-1102错误的核心原因。
- 统一参数排序:签名计算时的参数顺序必须和最终传给API的参数顺序完全一致,建议按key排序后再拼接queryString:
const sortedParams = Object.entries(params).sort((a, b) => a[0].localeCompare(b[0])); const queryString = sortedParams.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&'); - 校验时间戳有效性:确保
Date.now()返回毫秒级时间戳,且与币安服务器时间差在recvWindow(当前设置为5000ms)范围内,时间偏差过大也会引发签名类错误。 - 核对密钥配置:确认
CHAVE_API和CHAVE_SECRETA无多余空格、换行,密钥完全匹配币安后台配置。
问题2:手续费支付逻辑调整
币安默认用交易所得币种支付手续费(如BTC/USDT交易,买单手续费从获得的BTC中扣除,卖单手续费从获得的USDT中扣除),无需手动调整价格。原代码中手动计算priceWithCommission的逻辑错误,MARKET订单成交价格为实时盘口价,手动加价会导致参数无效或成交异常,正确做法:
- 删除所有手动计算手续费的代码,MARKET订单不需要传入price参数。
- 若需精确控制最终获得的币种数量,可改用LIMIT订单,或在下单前根据手续费率反向计算下单数量。
- 币安手续费折扣(如BNB支付享25%折扣)需在账户设置中开启,API会自动应用,无需手动计算。
修改后的示例代码:
async function novaOrdem(symbol, quantity, side) { const type = 'MARKET'; const recvWindow = 5000; const params = { symbol, quantity, side, type, timestamp: Date.now(), recvWindow }; // 按key排序参数,确保签名计算与传参顺序一致 const sortedParams = Object.entries(params).sort((a, b) => a[0].localeCompare(b[0])); const queryString = sortedParams.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&'); const signature = crypto.createHmac('sha256', CHAVE_SECRETA).update(queryString).digest('hex'); try { const { data } = await axios.post(`${API_URL}/api/v3/order`, null, { params: { ...params, signature }, headers: { 'X-MBX-APIKEY': CHAVE_API } }); console.log(data); } catch (erro) { console.error('Erro ao colocar a ordem:', erro.response.data); } }
内容的提问来源于stack exchange,提问作者programmerlearner
相关产品推荐
相关产品推荐

