Add Stripe Cancellation Webhook (#1682)
This commit is contained in:
parent
7492783964
commit
49e3878239
6 changed files with 77 additions and 1 deletions
1
Envfile
1
Envfile
|
|
@ -130,6 +130,7 @@ variable :SLACK_WEBHOOK_URL, :String, default: "Optional"
|
|||
# Stripe for payment system
|
||||
variable :STRIPE_PUBLISHABLE_KEY, :String, default: "Optional"
|
||||
variable :STRIPE_SECRET_KEY, :String, default: "Optional"
|
||||
variable :STRIPE_CANCELLATION_SECRET, :String, default: "Optional"
|
||||
|
||||
# For browser webpush notifications (webpush gem) (totally random base64 nums)
|
||||
variable :VAPID_PUBLIC_KEY, :String, default: "dGhpcyBpcyBkZXYudG8gdGVzdCBkYXRh"
|
||||
|
|
|
|||
39
app/controllers/stripe_cancellations_controller.rb
Normal file
39
app/controllers/stripe_cancellations_controller.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
class StripeCancellationsController < ApplicationController
|
||||
skip_before_action :verify_authenticity_token, only: :create
|
||||
|
||||
def create
|
||||
verify_stripe_signature
|
||||
unsubscribe_customer
|
||||
end
|
||||
|
||||
def verify_stripe_signature
|
||||
payload = request.body.read
|
||||
sig_header = request.env["HTTP_STRIPE_SIGNATURE"]
|
||||
|
||||
begin
|
||||
Stripe::Webhook.construct_event(
|
||||
payload, sig_header, Rails.configuration.stripe[:stripe_cancellation_secret]
|
||||
)
|
||||
rescue JSON::ParserError
|
||||
# Invalid payload
|
||||
status 400
|
||||
return
|
||||
rescue Stripe::SignatureVerificationError
|
||||
# Invalid signature
|
||||
status 400
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def unsubscribe_customer
|
||||
event = Stripe::Event.retrieve(params[:id])
|
||||
stripe_id = event.data.object.customer
|
||||
customer = Stripe::Customer.retrieve(stripe_id)
|
||||
monthly_dues = event.data.object.items.data[0].plan.amount
|
||||
user = User.where(stripe_id_code: stripe_id).first
|
||||
MembershipService.new(customer, user, monthly_dues).unsubscribe_customer
|
||||
render body: nil, status: 200
|
||||
rescue Stripe::APIConnectionError, Stripe::StripeError
|
||||
render body: nil, status: 400
|
||||
end
|
||||
end
|
||||
|
|
@ -42,6 +42,8 @@ class MembershipService
|
|||
end
|
||||
|
||||
def cancel_subscription
|
||||
return true if customer.subscriptions.none?
|
||||
|
||||
subscription.delete
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
Rails.configuration.stripe = {
|
||||
publishable_key: ApplicationConfig["STRIPE_PUBLISHABLE_KEY"],
|
||||
secret_key: ApplicationConfig["STRIPE_SECRET_KEY"]
|
||||
secret_key: ApplicationConfig["STRIPE_SECRET_KEY"],
|
||||
stripe_cancellation_secret: ApplicationConfig["STRIPE_CANCELLATION_SECRET"]
|
||||
}
|
||||
|
||||
Stripe.api_key = Rails.configuration.stripe[:secret_key]
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ Rails.application.routes.draw do
|
|||
resources :tags, only: [:index]
|
||||
resources :stripe_subscriptions, only: %i[create update destroy]
|
||||
resources :stripe_active_cards, only: %i[create update destroy]
|
||||
resources :stripe_cancellations, only: [:create]
|
||||
resources :live_articles, only: [:index]
|
||||
resources :github_repos, only: %i[create update]
|
||||
resources :buffered_articles, only: [:index]
|
||||
|
|
|
|||
32
spec/requests/stripe_cancellations_spec.rb
Normal file
32
spec/requests/stripe_cancellations_spec.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe "StripeCancellations", type: :request do
|
||||
let(:user) { create(:user) }
|
||||
let(:stripe_helper) { StripeMock.create_test_helper }
|
||||
|
||||
before do
|
||||
StripeMock.start
|
||||
allow_any_instance_of(StripeCancellationsController).to receive(:verify_stripe_signature).and_return(true)
|
||||
end
|
||||
|
||||
after { StripeMock.stop }
|
||||
|
||||
it "mocks a stripe cancellation webhook" do
|
||||
customer = Stripe::Customer.create(
|
||||
email: user.email,
|
||||
source: stripe_helper.generate_card_token,
|
||||
)
|
||||
MembershipService.new(customer, user, 12).subscribe_customer
|
||||
user.reload
|
||||
expect(user.monthly_dues).not_to eq(0)
|
||||
|
||||
event = StripeMock.mock_webhook_event(
|
||||
"customer.subscription.deleted",
|
||||
customer: user.stripe_id_code, total_count: 1,
|
||||
)
|
||||
post "/stripe_cancellations", params: event.as_json
|
||||
user.reload
|
||||
expect(user.monthly_dues).to eq(0)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue