Skip to content

Instantly share code, notes, and snippets.

@myf9000
Last active July 2, 2017 11:06
Show Gist options
  • Save myf9000/1c8d5576545bfad61da350e242254a76 to your computer and use it in GitHub Desktop.
Save myf9000/1c8d5576545bfad61da350e242254a76 to your computer and use it in GitHub Desktop.
class StripeContext
class UseCases
class HandleWebhook
EXPIRES_AT = Time.zone.now + 1.month
USER_PREMIUM_EXPIRES_AT = EXPIRES_AT + 1.day
CUSTOMER_NAME = "customer".freeze
EVENT_TYPES = {
"customer.subscription.created" => "created_subscription",
"invoice.payment_succeeded" => "continued_subscription",
"invoice.payment_failed" => "deleted_subscription",
"customer.created" => "created_customer",
"customer.deleted" => "deleted_customer",
"plan.created" => "created_plan",
}
attr_reader :stripe_handler, :email_service, :user_repository, :plan_repository, :event,
:subscription_repository, :get_premium_id_service
def initialize(
stripe_handler: Handlers::StripeHandler,
email_service: Services::SendStripeEmail,
user_repository: Repositories::UserRepository,
plan_repository: Repositories::PlanRepository,
subscription_repository: Repositories::SubscriptionRepository,
get_premium_id_service: Services::GetPremiumId
)
@stripe_handler = stripe_handler
@email_service = email_service
@user_repository = user_repository
@plan_repository = plan_repository
@subscription_repository = subscription_repository
@get_premium_id_service = get_premium_id_service
end
def call(event_id)
@event = stripe_handler.new.retrieve_event(event_id)
handle_event
end
private
def handle_event
return unless EVENT_TYPES.keys.include?(event.type)
self.send(EVENT_TYPES[event.type])
end
def created_customer
new_customer_email = stripe_handler.new.retrieve_customer(customer_id)
new_customer = user_repository.new.find_user_by_email(new_customer_email)
return unless new_customer.present?
user_repository.new.set_customer_id(new_customer, customer_id)
end
def deleted_customer
return unless user.present?
user_repository.new.remove_premium_membership(user)
user_repository.new.remove_customer_id(user)
end
def created_plan
return if plan_repository.new.plan_exist?(resource_params.id)
plan_repository.new.create_plan(plan_params)
end
def created_subscription
plan = plan_repository.new.find_by_plan_id(subscription_params[:plan_id])
return unless user.present? && plan.present?
subscription_repository.new.create_subscription(subscription_params, plan.id)
user_repository.new.set_premium_id(user, get_premium_id_service.new.call)
end
def deleted_subscription
return unless user.present?
subscription_repository.new.deactivated_subscription(resource_params.subscription)
email_service.new.send_payment_error_email(user)
email_service.new.send_deactivated_premium_email(user)
deleted_customer
end
def continued_subscription
return unless user.present?
user_repository.new.set_premium_expires_at(user, USER_PREMIUM_EXPIRES_AT)
subscription_repository.new.update_subscription_expiration_time(
resource_params.subscription, EXPIRES_AT
)
email_service.new.send_activated_premium_email(user)
end
def user
@user ||= begin
user_repository.find_user_by_customer_id(customer_id)
end
end
def customer_id
@customer ||= begin
resource_params.object == CUSTOMER_NAME ? resource_params.id : resource_params.customer
end
end
def resource_params
@resource_params ||= event.data.object
end
def subscription_params
{
subscription_id: resource_params.id,
user_id: user.id,
expiration_time: Time.zone.at(resource_params.current_period_end),
plan_id: resource_params.plan.id,
}
end
def plan_params
{
plan_id: resource_params.id,
name: resource_params.name,
amount: resource_params.amount,
interval: resource_params.interval,
currency: resource_params.currency,
}
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment