Skip to main content

Webhook Common Rules

For Security Purpose, Binance will add signature for webhook notification. Partner needs to verify the signature using the public key issued from Binance Pay.

Protocol Rules

The following specifies the rules for calling the Webhook Notification from Binance payment.

RuleDescription
Transfer ModeUse HTTPS for secure transactions.
Submit ModePOST/GET, depends on the API.
Data FormatData submitted and response are both in application/json format.
Char EncodingUse UTF-8 character encoding.
Signature AlgorithmRSA, asymmetric cryptographic algorithm
Signature RequirementSignature-checking is required for requesting and receiving data.
Logic JudgmentDetermine protocol field, service field and transaction status.

Request Header

AttributesTypeRequiredLimitationDescription
BinancePay-Certificate-SNlongY-MD5 hash value of public key
BinancePay-NoncestringYmust be 32 digitsA random string with 32 bytes, e.g. random ascii decimal within a-z and A-Z and loop 32 times to form a random string
BinancePay-TimestampstringY-UnixTimestamp in milliseconds
BinancePay-SignaturestringY-signature, generated by Binance Pay

Verify the Signature

Build the payload

Java

String payload = timestamp + "\n" + nonce + "\n" + body + "\n";

PHP

$payload = $headers['Binancepay-Timestamp'] . "\n" . $headers['Binancepay-Nonce'] . "\n" . $entityBody . "\n";

Note:

  • ‘\n’ is LF, ASCII value is '0x0A'

Decode the Signature with Base64

Java

byte[] decodedSignature = Base64.getDecoder().decode(signature);

PHP

$decodedSignature = base64_decode ( $headers['Binancepay-Signature'] );

Verify the content with public key

Note:

  • Hash algorithm should use SHA256

Sample Java code is here, together with org.bouncycastle toolkit.

 // input: pubKeyStr, decodedSignature, payload
PEMParser pubParser = new PEMParser(new StringReader(pubKeyStr))
SubjectPublicKeyInfo pubKeyObj = (SubjectPublicKeyInfo) pubParser.readObject();
AsymmetricKeyParameter pubKey = PublicKeyFactory.createKey(pubKeyObj);

byte[] payloadBytes = payload.getBytes(StandardCharsets.UTF_8);
RSADigestSigner verifier = new RSADigestSigner(new SHA256Digest());
verifier.init(false, pubKey);
verifier.update(payloadBytes, 0, payloadBytes.length);

return verifier.verifySignature(decodedSignature);

PHP

openssl_verify($payload, $decodedSignature, $publicKey, OPENSSL_ALGO_SHA256 );