Verifying Webhooks
Check that webhooks are genuinely sent from Paddle
We send a signature field with each webhook that can be used to verify that the webhook was sent by Paddle.
We use public/private key encryption to allow you to verify these requests. Follow the step-by-step guide below to verify a Paddle signature.
- Get Your Public Key – this can be found in your Seller Dashboard under Developer Tools > Public Key.
- Get the Webhook Signature – the signature is included on each webhook with the attribute
p_signature
. - Remove the signature from the response – the signature should not be included in the array of fields used in verification.
- Sort remaining fields – ensure the fields are listed in a standard order, sorted by key name, e.g. by using
ksort()
. - Serialize and sign the array – verify the serialized array against the signature using SHA1 with your public key.
Code examples
<?php
// Your Paddle 'Public Key'
$public_key_string =
"-----BEGIN PUBLIC KEY-----" . "\n" .
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAncWOfnvXciow60nwb7te" . "\n" .
"uwbluhc2WLdy8C3E4yf+gQEGjR+EXwDogWAmpJW0V3cRGhe41BBtO0vX39YeEjh3" . "\n" .
"tkCIT4JTkR4yCXiXJ/tYGvsCAwEAAQ==" . "\n" .
"-----END PUBLIC KEY-----";
$public_key = openssl_get_publickey($public_key_string);
// Get the p_signature parameter & base64 decode it.
$signature = base64_decode($_POST['p_signature']);
// Get the fields sent in the request, and remove the p_signature parameter
$fields = $_POST;
unset($fields['p_signature']);
// ksort() and serialize the fields
ksort($fields);
foreach($fields as $k => $v) {
if(!in_array(gettype($v), array('object', 'array'))) {
$fields[$k] = "$v";
}
}
$data = serialize($fields);
// Verify the signature
$verification = openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA1);
if($verification == 1) {
echo 'Yay! Signature is valid!';
} else {
echo 'The signature is invalid!';
}
?>