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.
Rule | Description |
---|---|
Transfer Mode | Use HTTPS for secure transactions. |
Submit Mode | POST/GET, depends on the API. |
Data Format | Data submitted and response are both in application/json format. |
Char Encoding | Use UTF-8 character encoding. |
Signature Algorithm | RSA, asymmetric cryptographic algorithm |
Signature Requirement | Signature-checking is required for requesting and receiving data. |
Logic Judgment | Determine protocol field, service field and transaction status. |
Request Header
Attributes | Type | Required | Limitation | Description |
---|---|---|---|---|
BinancePay-Certificate-SN | long | Y | - | MD5 hash value of public key from Query Certificate API |
BinancePay-Nonce | string | Y | must be 32 digits | A 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-Timestamp | string | Y | - | UnixTimestamp in milliseconds |
BinancePay-Signature | string | Y | - | 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 );