Skip to content

Instantly share code, notes, and snippets.

@involer
Created January 19, 2015 14:15
Show Gist options
  • Save involer/5dbcd3de85868e364d48 to your computer and use it in GitHub Desktop.
Save involer/5dbcd3de85868e364d48 to your computer and use it in GitHub Desktop.
Paddle Webhook Validation (Ruby)
#test data
data = {
'customer_email' => "test-user@blackhole.io",
'customer_name' => "Test User",
'p_country' => "US",
'p_coupon' => "",
'p_coupon_savings' => 0,
'p_currency' => "",
'p_earnings' => "[]",
'p_order_id' => 261205,
'p_paddle_fee' => 7.6,
'p_price' => "10.00",
'p_sale_gross' => "10.00",
'p_quantity' => 1,
'p_tax_amount' => 0,
'passthrough' => "Example passthrough",
'product_id' => "1",
'quantity' => 1,
'transaction_id' => "800270865cbc60556a9e4bf65dca7a76",
'vendor_shared_secret' => "323c9a72281d4d555fdd89f2c7ecb8bc6e0e1197e352276840a15b739b2a94e8",
"p_signature" => "T7Tbppzd++Y600hfmTF7uzEUR6Ga+LQ2DkzcV64A6bxBA9DWvI2xqfkrIbRc/sinHchsrhLyT2WVRkllWFiClmnYCuZ3A3MhlgHNbmMly7mqtxg1tEZEkE4Ym3v+z/PGZXGVqFs6h2JTqSZtTLC6wV8PEpVuHNtCJ2JGEOzzTR1qTPKRRetEw2uzJEpqKuM2Dsc9APp4F1JVjUTLJpwb3JDpOLIylnU2G4sUBpRm8Zb1UPGNSOkf5/8Alq4mu03c0ZE0ohxao3cNNXEwMlCIcFxvEHNu8TRHJUknfpAS9YFHn4Hz3E95rcAlh2ojsJMpDH6p2mD9r7sEZb/AzYKbiQhNgYJhcqPRb40s37/NQFDZ0xhxaMRZ3tLGYc3SGaun/FQhBiMVLPX0y8OQoFQiJAVKmA3s6pwzgIQAQzgwuug5Ohp3phARSrUyR18IEYad0PMBCTI21vngdFJc/GGn4eATp0pJYiDLNzCjkHyp0WQuiV+6QvmfMkViD+FS4CX4mqjgsGLb/joKv53rojQsHU2SrkVRmHLcpiCugfqAto7qkn+XDb9Vy+4CaJaTk/WI9LFgrLAIau8kN6kK64bBPIIq/xh2auFPdSlAotIrfy3ZMLPpma/gjkYjuZUAtlC3JWW5lvDJ/QaL1nJbxSJniSDOrmPeDSIp8nVX58jnUnY="
}
require 'base64'
require 'php_serialize'
require 'openssl'
public_key = '-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAw9rtXyw8ZkVAyUOyGS5P
VzzzmA1CZFoT+2cdLbVb51G4kYWGKh4lBgrR/x2P5UVAzJM658XkJlKSF6mtkzS2
4FUfM5w8rHEv1DA1yYs3IPYUuUNjECul/RWgZgJGQ77VnWf41MByrTxbWRu1ug8l
tqdAhymFMeyVcGkx2b3kB83CwmcSKTj7uSHmtn4HMycqTzWNiTQN48/47AEu04wh
BGQfo9RCEAMKVSs5UlNcapmJLbg7z/Gk3tZHSt0uy6xKBy5ByOqIDegXLHSgw7JU
h3Z5ORUptpksHdqFUj1TLhOpJ9MTWYn2TvSjgIlpFDoZT2xpCh4W96CYgd2Etfid
sPE4ht0iPAZ4G/uofo+mAqveR6bWKdPhNES6FsJ3bYigg7TdoiJpiKqdn5cnPDZr
/BKQ/UQmZv0o13X+byFrgPj3YxsY5PP8P7aan7/PdBqLB3G8D68PAkPSiXmjMdiH
fhm3d8+ZUhUg5yCa0d2HWFPKx1S6sqIBlnTgtgcKVYpMPsWaN79CViS1oZfe9UeH
ImgjkocCGk7h+Bm7FKF7okTuWHDjqLbclCeOGUVCLZ0Qd1m4kqZUVr7ouueHPBhe
mMNuOK5tjLr0idceE6OpDkqLS/t+hyjrUhGeWy/cZ5Qu9N95PmiQ5CdmN9EykPUC
Tim9/IaQjr/pTWV0GE/hKR0CAwEAAQ==
-----END PUBLIC KEY-----'
# Get the p_signature parameter & base64 decode it.
signature = Base64.decode64(data['p_signature'])
# Remove the p_signature parameter
data.delete('p_signature')
# Ensure all the data fields are strings
data.each {|key, value|data[key] = String(value)}
# Sort the data
data_sorted = data.sort_by{|key, value| key}
# and serialize the fields
# serialization library is available here: http://www.aagh.net/projects/ruby-php-serialize
data_serialized = PHP.serialize(data_sorted, true)
# verify the data
digest = OpenSSL::Digest::SHA1.new
pub_key = OpenSSL::PKey::RSA.new(public_key).public_key
verified = pub_key.verify(digest, signature, data_serialized)
if verified
puts "Yay! Signature is valid!"
else
puts "The signature is invalid!"
end
@dropkickfish
Copy link

@nkrasnogor did you ever solve this? I've been searching all day and found a lot of people with similar problems, but no solution as of yet

@nkrasnogor
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment