mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 21:29:38 +02:00
* Basic plaid data model and linking * Remove institutions, add plaid items * Improve schema and Plaid provider * Add webhook verification sketch * Webhook verification * Item accounts and balances sync setup * Provide test encryption keys * Fix test * Only provide encryption keys in prod * Try defining keys in test env * Consolidate account sync logic * Add back plaid account initialization * Plaid transaction sync * Sync UI overhaul for Plaid * Add liability and investment syncing * Handle investment webhooks and process current day holdings * Remove logs * Remove "all" period select for performance * fix amount calc * Remove todo comment * Coming soon for investment historical data * Document Plaid configuration * Listen for holding updates
73 lines
2.2 KiB
Ruby
73 lines
2.2 KiB
Ruby
class WebhooksController < ApplicationController
|
|
skip_before_action :verify_authenticity_token
|
|
skip_authentication
|
|
|
|
def plaid
|
|
webhook_body = request.body.read
|
|
plaid_verification_header = request.headers["Plaid-Verification"]
|
|
|
|
Provider::Plaid.validate_webhook!(plaid_verification_header, webhook_body)
|
|
Provider::Plaid.process_webhook(webhook_body)
|
|
|
|
render json: { received: true }, status: :ok
|
|
rescue => error
|
|
render json: { error: "Invalid webhook: #{error.message}" }, status: :bad_request
|
|
end
|
|
|
|
def stripe
|
|
webhook_body = request.body.read
|
|
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
|
|
client = Stripe::StripeClient.new(ENV["STRIPE_SECRET_KEY"])
|
|
|
|
begin
|
|
thin_event = client.parse_thin_event(webhook_body, sig_header, ENV["STRIPE_WEBHOOK_SECRET"])
|
|
|
|
event = client.v1.events.retrieve(thin_event.id)
|
|
|
|
case event.type
|
|
when /^customer\.subscription\./
|
|
handle_subscription_event(event)
|
|
when "customer.created", "customer.updated", "customer.deleted"
|
|
handle_customer_event(event)
|
|
else
|
|
Rails.logger.info "Unhandled event type: #{event.type}"
|
|
end
|
|
|
|
rescue JSON::ParserError
|
|
render json: { error: "Invalid payload" }, status: :bad_request
|
|
return
|
|
rescue Stripe::SignatureVerificationError
|
|
render json: { error: "Invalid signature" }, status: :bad_request
|
|
return
|
|
end
|
|
|
|
render json: { received: true }, status: :ok
|
|
end
|
|
|
|
private
|
|
|
|
def handle_subscription_event(event)
|
|
subscription = event.data.object
|
|
family = Family.find_by(stripe_customer_id: subscription.customer)
|
|
|
|
if family
|
|
family.update(
|
|
stripe_plan_id: subscription.plan.id,
|
|
stripe_subscription_status: subscription.status
|
|
)
|
|
else
|
|
Rails.logger.error "Family not found for Stripe customer ID: #{subscription.customer}"
|
|
end
|
|
end
|
|
|
|
def handle_customer_event(event)
|
|
customer = event.data.object
|
|
family = Family.find_by(stripe_customer_id: customer.id)
|
|
|
|
if family
|
|
family.update(stripe_customer_id: customer.id)
|
|
else
|
|
Rails.logger.error "Family not found for Stripe customer ID: #{customer.id}"
|
|
end
|
|
end
|
|
end
|