我正在尝试从 binance pay api 获取“创建订单”api,以便在我的 kotlin android 应用程序中进行付款。我正在按照 api 文档 来构建有效负载和签名,但不幸的是它不起作用。 我收到此错误:“errorMessage”:“此请求的签名无效。”
有人可以帮忙吗?
private fun createSignature(payload: String, secretKey: String): String {
val sha512HMAC = Mac.getInstance("HmacSHA512")
val secretKeySpec =
SecretKeySpec(secretKey.toByteArray(), "HmacSHA512")
sha512HMAC.init(secretKeySpec)
val digest = sha512HMAC.doFinal(payload.toByteArray())
return digest.toHex()
}
val timestamp = System.currentTimeMillis() + clockOffset
val nonceStr = generateNonce()
val body = Gson().toJson(
OrderRequest(
Env("APP"),
merchantTradeNb,
0.02,
"USDT",
Goods("01", "D000", "7876763A3C", "phone", "Good new phone")
)
)
val payload = timestamp.toString() + "\n" + nonceStr + "\n" + body + "\n"
val signature: String = createSignature(
payload.toByteArray(Charsets.UTF_8).toString(), secretKey
).uppercase()
val retrofitData = retrofitBuilder.binanceApi.createOrder(
"application/json", timestamp, nonceStr, certSn, signature, body
)
retrofitData.enqueue(object : Callback<OrderResponse> {
override fun onResponse(
call: Call<OrderResponse>,
response: Response<OrderResponse>,
) {
response.body()
}
override fun onFailure(call: Call<OrderResponse>, t: Throwable) {
}
})
}
interface BinancePayApi {
@POST("/binancepay/openapi/v2/order")
fun createOrder(
@Header("Content-type") contentType: String,
@Header("BinancePay-Timestamp") timestamp: Long,
@Header("BinancePay-Nonce") nonce: String,
@Header("BinancePay-Certificate-SN") apiKey: String,
@Header("BinancePay-Signature") signature: String,
@Body request: String
): Call<OrderResponse>
}
我猜问题出在签名,根据您需要执行此操作的文档
String signature = hex(hmac("sha512", payload, secretKey)).toUpperCase()
因此,要在
kotlin
中执行此操作,您可以按如下方式执行此操作
fun hmac(algorithm: String, data: String, secretKey: String): ByteArray {
val secret = SecretKeySpec(secretKey.toByteArray(), algorithm)
val mac = Mac.getInstance(algorithm)
mac.init(secret)
return mac.doFinal(data.toByteArray())
}
然后你需要将其转换为
hex
,这样你就可以创建这个方法(我看到你正在使用这个.toHex()
,但我不知道你的实现)
fun hex(bytes: ByteArray): String {
val hexChars = "0123456789ABCDEF".toCharArray()
val result = StringBuilder(bytes.size * 2)
for (b in bytes) {
result.append(hexChars[b.toInt().shr(4) and 0x0f])
result.append(hexChars[b.toInt() and 0x0f])
}
return result.toString()
}
然后你唯一需要做的就是把它包起来,你可以这样做:
val signature = hex(hmac("SHA-512", payload, secretKey)).toUpperCase()
我想知道您遇到的问题是否是您使用的是
HmacSHA512
而不是 SHA-512
。
您只需检查您的 https://merchant.binance.com/ 账户是否正在接受审核,您无法进行任何 API 调用,只需等待您的个人资料审核一旦通过,您就可以使用 API 执行任何交易 在此输入图片描述
我正在阅读您发布的文档,并且阅读了以下示例: (https://developers.binance.com/docs/binance-pay/app-integration)
字符串有效负载=“certSn=317c110ebf7baf641e8f49ab6851331737dbe98541947c53b9dbba27f8c8414f”+“&”+“merchantId=98765987”+“&”+“noncestr=5K8264ILTKCH16CQ2502SI8ZNM TM67VS" + "&" + "prepayId=98765987" + "&"+ "timeStamp=1618302830073";字符串签名 = hex(hmac("sha512", Payload, SecretKey)).toUpperCase();
在你的 createSignature 方法中我没有看到这个逻辑。