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 );