Skip to content

Instantly share code, notes, and snippets.

@phawk
Created February 20, 2019 16:03
Show Gist options
  • Save phawk/9d36134260057ee52afe8e290b310b33 to your computer and use it in GitHub Desktop.
Save phawk/9d36134260057ee52afe8e290b310b33 to your computer and use it in GitHub Desktop.
Benmudge.com PayHere Webhooks integration
module Events
class PayhereWebhooksController < ApplicationController
skip_before_action :authenticate_user!
skip_before_action :verify_authenticity_token
def create
return head 401 unless valid_signature?
if payment_params[:status] == "success"
user = find_or_create_user
payment = find_or_create_payment_for(user)
if new_user?
SlackNotifierJob.perform_async("#{user.name} (#{user.email}) just subscribed for £#{payment.amount}")
UserMailer.welcome(user).deliver_later
else
SlackNotifierJob.perform_async("#{user.name} (#{user.email}) subscription just renewed for £#{payment.amount}")
end
end
head :no_content
end
private
def valid_signature?
digest = OpenSSL::Digest.new("sha1")
expected = OpenSSL::HMAC.hexdigest(digest, ENV["PAYHERE_SHARED_SECRET"].to_s, request.raw_post)
Rack::Utils.secure_compare(expected, request.headers["HTTP_X_SIGNATURE"])
end
def find_or_create_payment_for(user)
user.payments.find_by(payhere_id: payment_params[:payhere_id]) || user.payments.create!(payment_params)
end
def new_user?
@new_user.present?
end
def find_or_create_user
if (user = User.find_by(email: user_params[:email]))
user.update(active_until: (1.month.from_now + 1.day).beginning_of_day)
user
else
@new_user = true
User.create!(user_params)
end
end
def user_params
{
name: params.dig(:customer, :name),
email: params.dig(:customer, :email),
password: SecureRandom.hex(16),
subscription_status: "active",
active_until: payment_params[:amount_in_cents] < 2001 ? (1.month.from_now + 1.day).beginning_of_day : (3.months.from_now + 1.day).beginning_of_day
}
end
def payment_params
{
amount_in_cents: params.dig(:payment, :amount).to_i * 100,
payhere_id: params.dig(:payment, :hashid),
status: params.dig(:payment, :status),
secure_token: params.dig(:payment, :secure_token),
card_brand: params.dig(:payment, :card_brand),
card_last4: params.dig(:payment, :card_last4)
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment