Created
January 24, 2021 18:53
-
-
Save subomi/98eae370376268f341eaa3f4735a6f47 to your computer and use it in GitHub Desktop.
Handle Paystack webhook validation in Ruby.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Controller to handle Event. | |
class PaystackController < ApplicationController | |
skip_before_action :authorize_request, only: :webhook | |
def webhook | |
paystack_instance = PaystackObject.instance | |
valid_event = paystack_instance.verify_webhook_event?(request) | |
raise StandardError, 'Phony event - Not Paystack' unless valid_event | |
render status: 200, plain: "Ok\n" | |
# This works if you have a job system in place. | |
# Else, keep to handle the transaction before line 10. | |
body = params.permit! | |
body = body.to_hash | |
HandlePaystackWebhookJob.perform_later(body) | |
end | |
end | |
# PaystackObject: This class validates each request, to check | |
# If it's from Paystack or not. | |
class PaystackObject | |
include Singleton | |
attr_accessor :paystack_obj | |
WHITELISTED_IPS = ['52.31.139.75', '52.49.173.169', '52.214.14.220'].freeze | |
def initialize | |
secret_key = ENV['PAYSTACK_SECRET_KEY'].split(' ')[1] | |
@paystack_obj = Paystack.new(ENV['PAYSTACK_PUBLIC_KEY'], secret_key) | |
end | |
def verify_webhook_event?(request) | |
verify_ip_address(request.remote_ip) && verify_header_signature(request) | |
end | |
private | |
def verify_ip_address(ip_address) | |
WHITELISTED_IPS.include?(ip_address) | |
end | |
def verify_header_signature(request) | |
body = request.body.string | |
hash = OpenSSL::HMAC.hexdigest('SHA512', @paystack_obj.private_key, body) | |
hash == request.headers['HTTP_X_PAYSTACK_SIGNATURE'] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment