Binance Pay: "Signature for this request is not valid" error with PHP cURL

Viewed 651

I'm using PHP cURL in order to connect to Binance Pay API. I get the following error:

{"status":"FAIL","code":"400002","errorMessage":"Signature for this request is not valid."}

Here is my code:

// Generate nonce string
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$nonce = '';
for($i=1; $i <= 32; $i++)
{
    $pos = mt_rand(0, strlen($chars) - 1);
    $char = $chars[$pos];
    $nonce .= $char;
}
$ch = curl_init();
$timestamp = round(microtime(true) * 1000);
// Request body
$request = array(
    "merchantTradeNo" => "12485634875fJhdd56",
    "totalFee" => 15,
    "productDetail" => "productDetail",
    "currency" => "BUSD",
    "returnUrl" => "",
    "tradeType" => "WEB",
    "productType" => "productType",
    "productName" => "ProductName"
);
$json_request = json_encode($request);
$payload = $timestamp."\n".$nonce."\n".$json_request."\n";
$signature = strtoupper(hash_hmac('SHA512',$payload,$binance_pay_secret));
$headers = array();
$headers[] = "Content-Type: application/json";
$headers[] = "BinancePay-Timestamp: $timestamp";
$headers[] = "BinancePay-Nonce: $nonce";
$headers[] = "BinancePay-Certificate-SN: $binance_pay";
$headers[] = "BinancePay-Signature: $signature";

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, "https://bpay.binanceapi.com/binancepay/openapi/order");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);

$result = curl_exec($ch);
if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); }
curl_close ($ch);

Regarding the documentation, everything seems ok, but it's not, so there is something wrong. Any idea? Thanks!

2 Answers

In python (and most likely in PHP as well) json encode is slightly modifying the request json by adding spaces and/or escaping quotes. The Binance Pay API requires the json string to be exactly how it is in the documentation. That is, with no extra spaces.

You forgot to add this

curl_setopt($ch, CURLOPT_POSTFIELDS, $json_request);
Related