无法正确发送带有 Volley POST 请求的市价单 [响应:此请求的签名无效]

时间:2021-01-25 21:18:20

标签: android api post android-volley binance

StringRequest 看起来工作正常,除了我尝试发送的签名。

我已经知道,如果其中任何一项不正确,Signature 就会失败:

  • 如果您没有将签名放在 params Map 中的最后一个键处。
  • 如果 API_SECRET 不正确,即使是一个空格。

我已经放置了所有必需的密钥,如果缺少一个,API 会返回适当的警告。

我使用 Python 获得了完全相同的签名,具有相同的时间戳,并且该顺序在 Python 中完美运行,但不适用于 Volley (Java)。

我担心 Volley 在发送订单时会更改相同值的格式,这就是签名与 Binance API 不匹配的原因。

我做错了什么?

package com.example.volleypost;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.android.volley.toolbox.StringRequest;
import com.android.volley.AuthFailureError;
import com.android.volley.toolbox.Volley;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.Response;
import com.android.volley.Request;
import java.util.LinkedHashMap;
import android.text.TextUtils;
import org.json.JSONObject;
import java.util.Calendar;
import java.util.HashMap;
import android.util.Log;
import java.util.Map;

public class MainActivity extends AppCompatActivity
{
    private final String TAG = "TAG";

    private final String API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    private final String API_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    private RequestQueue requestQueue;
    private StringRequest jsonObjectRequest;
    public String requestBody;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        requestQueue = Volley.newRequestQueue(this);

        JSONObject obj = new JSONObject();
        try{
            obj.put("symbol","BNBBUSD");
            requestBody = obj.toString();
        }catch (Exception e){}


        jsonObjectRequest = getStringRequest();
        requestQueue.add(jsonObjectRequest);
    }

    private StringRequest getStringRequest()
    {
        return new StringRequest(
                Request.Method.POST, "https://api.binance.com/api/v3/order" ,

                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response)
                    {
                        Log.d(TAG , "Response : " + response );
                    }
                }, new Response.ErrorListener()
        {
            @Override
            public void onErrorResponse(VolleyError error)
            {
                try
                {
                    String responseBody = new String(error.networkResponse.data, "utf-8");
                    JSONObject data = new JSONObject(responseBody);
                    String message = data.optString("msg");
                    Log.d(TAG, "Response Error = " + message);
                }
                catch (Exception e){}
            }
        })
        {

               @Override
               protected Map<String, String> getParams()
               {
                   Map<String, String> data = new LinkedHashMap<>();

                   String timeStamp, signature, formatedData;

                   try
                   {
                       data.put("symbol", "BNBBUSD");
                       data.put("side", "SELL");
                       data.put("type", "MARKET");
                       data.put("quantity", "1.12");

                       timeStamp = String.format("%d", Calendar.getInstance().getTimeInMillis());
                       data.put("timestamp",timeStamp);

                       formatedData = formatData(data);

                       Log.d(TAG,formatedData + "\n");

                       signature = SignatureGenerator.getHmacSignature(formatedData, API_SECRET);
                       data.put("signature", signature);

                       Log.d(TAG,data.toString() + "\n");

                       return data;
                   }
                   catch (Exception e)
                   {
                       return null;
                   }
               }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError
            {
                Map<String,String> headers = new HashMap<>();
                headers.put("X-MBX-APIKEY", API_KEY);
                return headers;
            }
        };
    }

    public String formatData(Map<String,String> data)
    {
        String[] valuesArray = new String[data.size()];

        int i = 0;
        for (String key : data.keySet())
        {
            valuesArray[i] =  key + "=" + data.get(key);
            i++;
        }
        return TextUtils.join("&",valuesArray);
    }
}

我收到了这样的回复:

symbol=BNBBUSD&side=SELL&type=MARKET&quantity=1.12&timestamp=1610625131172

{symbol=BNBBUSD, side=SELL, type=MARKET, quantity=1.12, timestamp=1610625131172, signature=959725ca183e8dd024961c57b9be9e371fe59f81c98693820421b3df0314acbd}

Response Error = Signature for this request is not valid.

0 个答案:

没有答案