iOS调用Binance API下单时遇-1022签名无效错误求助
Fixing Binance API -1022 Signature Error on iOS (Swift)
Looks like you're hitting a classic issue with how Binance expects POST requests to be structured, even though your GET-based account endpoints work fine. Let's break down the problem and fix your code step by step.
The Root Cause
Your code has the HTTP method handling reversed for parameter placement:
- For
GETrequests, Binance expects parameters in the URL query string (not the request body) - For
POSTrequests (like placing an order), Binance expects parameters in the request body asx-www-form-urlencodeddata (not appended to the URL)
In your current code, you're putting GET params in the body and POST params in the URL — this breaks the signature validation for POST endpoints like order placement.
Additional Checks to Confirm
Before jumping to fixes, let's verify a couple of other common pitfalls:
- Ensure your
timestampis in milliseconds (your code does this correctly withInt(Date().timeIntervalSince1970 * 1000), so that's good) - Make sure you're using the full secret key from Binance (no extra spaces or truncation)
- Confirm all required parameters for the endpoint are included (you have
symbol,side,type,recvWindow,quantity,timestampfor MARKET sell — that's complete)
Corrected Code Implementation
Here's the fixed version of your requestFor(api:) method, with comments explaining the changes:
public override func requestFor(api: APIType) -> NSMutableURLRequest { let mutableURLRequest = api.mutableRequest guard let key = key, let secret = secret, api.authenticated else { return mutableURLRequest } var postData = api.postData // Add your order parameters (keep these as is) postData["symbol"] = "BNBBTC" postData["side"] = "SELL" postData["type"] = "MARKET" postData["recvWindow"] = "5000" postData["quantity"] = "0.1" postData["timestamp"] = "\(Int(Date().timeIntervalSince1970 * 1000))" // Generate signature from the full query string of parameters guard let hmac_sha = try? HMAC(key: secret, variant: .sha256).authenticate(Array(postData.queryString.utf8)) else { // Handle error if signature generation fails return mutableURLRequest } let signature = Data(bytes: hmac_sha).toHexString() postData["signature"] = signature // Adjust parameter placement based on HTTP method switch api.httpMethod { case .GET: // For GET: append parameters to URL query string if let urlString = mutableURLRequest.url?.absoluteString, !postData.queryString.isEmpty { let newUrlString = urlString + "?" + postData.queryString mutableURLRequest.url = URL(string: newUrlString) } case .POST: // For POST: set parameters as x-www-form-urlencoded body mutableURLRequest.httpBody = postData.data mutableURLRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") } // Add API key header mutableURLRequest.setValue(key, forHTTPHeaderField: "X-MBX-APIKEY") // Debug print (keep if needed) if let data = postData.data, let string = String(data: data, encoding: .utf8) { api.print("Request Data: \(string)", content: .response) } return mutableURLRequest }
Key Changes Explained
- Reversed HTTP Method Handling:
GETrequests now append parameters to the URL (correct for account info endpoints)POSTrequests now set the parameters as the request body (required for order placement)
- Added Content-Type Header: For POST requests, Binance requires
application/x-www-form-urlencodedto properly parse the body parameters - Guard Clauses: Added early returns for missing auth keys to clean up the code
- Cleaner Parameter Handling: Switched to a
switchstatement for better readability of method-specific logic
Final Notes
- Double-check that your
postData.queryStringmethod correctly sorts parameters by key in ASCII order — Binance requires this for signature validation (most query string helpers do this by default, but it's worth confirming) - If you're still getting errors, enable debug logging to print out the exact query string used for signing and compare it to what Binance expects (you can cross-verify by generating a valid signature manually using the parameters you're sending)
内容的提问来源于stack exchange,提问作者Moin Shirazi
相关产品推荐
相关产品推荐

