mirror of
https://github.com/neocities/neocities.git
synced 2026-05-26 15:02:03 +00:00
fix for paypal webhook cancel
This commit is contained in:
@@ -1,7 +1,60 @@
|
||||
post '/webhooks/paypal' do
|
||||
return 403 unless valid_paypal_webhook_source?
|
||||
|
||||
if paypal_subscription_ended_ipn?
|
||||
site = paypal_ipn_site
|
||||
|
||||
if site
|
||||
stripe_active = site.stripe_paying_supporter?
|
||||
|
||||
site.paypal_active = false
|
||||
site.paypal_profile_id = nil
|
||||
site.paypal_token = nil
|
||||
|
||||
unless stripe_active
|
||||
site.plan_type = nil
|
||||
site.plan_ended = true
|
||||
end
|
||||
|
||||
site.save_changes validate: false
|
||||
|
||||
unless stripe_active
|
||||
EmailWorker.perform_async({
|
||||
from: Site::FROM_EMAIL,
|
||||
to: site.email,
|
||||
subject: '[Neocities] Supporter plan has ended',
|
||||
body: Tilt.new('./views/templates/email/supporter_ended.erb', pretty: true).render(self)
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
'ok'
|
||||
end
|
||||
|
||||
def paypal_subscription_ended_ipn?
|
||||
%w[
|
||||
recurring_payment_profile_cancel
|
||||
recurring_payment_expired
|
||||
recurring_payment_suspended
|
||||
recurring_payment_suspended_due_to_max_failed_payment
|
||||
subscr_cancel
|
||||
subscr_eot
|
||||
].include?(params[:txn_type].to_s)
|
||||
end
|
||||
|
||||
def paypal_ipn_site
|
||||
profile_id = params[:recurring_payment_id] ||
|
||||
params[:recurring_payment_profile_id] ||
|
||||
params[:rp_profile_id] ||
|
||||
params[:profile_id] ||
|
||||
params[:subscr_id]
|
||||
|
||||
return nil if profile_id.blank?
|
||||
|
||||
Site.where(paypal_profile_id: profile_id).first
|
||||
end
|
||||
|
||||
def valid_paypal_webhook_source?
|
||||
return true if self.class.test?
|
||||
return true if request.ip == '127.0.0.1'
|
||||
|
||||
@@ -66,6 +66,70 @@ describe 'tipping' do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'paypal supporter IPN' do
|
||||
include Rack::Test::Methods
|
||||
|
||||
def app
|
||||
Sinatra::Application
|
||||
end
|
||||
|
||||
before do
|
||||
EmailWorker.jobs.clear
|
||||
@site = Fabricate :site
|
||||
@site.update(
|
||||
paypal_active: true,
|
||||
paypal_profile_id: 'I-123',
|
||||
paypal_token: 'EC-123',
|
||||
plan_type: 'supporter',
|
||||
plan_ended: false
|
||||
)
|
||||
end
|
||||
|
||||
it 'ends a PayPal supporter membership when PayPal cancels the recurring profile' do
|
||||
post '/webhooks/paypal', paypal_supporter_ipn_hash
|
||||
|
||||
_(last_response.status).must_equal 200
|
||||
@site.reload
|
||||
_(@site.values[:paypal_active]).must_equal false
|
||||
_(@site.paypal_profile_id).must_be_nil
|
||||
_(@site.paypal_token).must_be_nil
|
||||
_(@site.values[:plan_type]).must_be_nil
|
||||
_(@site.plan_ended).must_equal true
|
||||
|
||||
_(EmailWorker.jobs.length).must_equal 1
|
||||
args = EmailWorker.jobs.first['args'].first
|
||||
_(args['to']).must_equal @site.email
|
||||
_(args['subject']).must_equal '[Neocities] Supporter plan has ended'
|
||||
end
|
||||
|
||||
it 'clears stale PayPal fields without ending an active Stripe membership' do
|
||||
@site.update(
|
||||
stripe_customer_id: 'cus_123',
|
||||
stripe_subscription_id: 'sub_123',
|
||||
plan_type: 'supporter',
|
||||
plan_ended: false
|
||||
)
|
||||
|
||||
post '/webhooks/paypal', paypal_supporter_ipn_hash
|
||||
|
||||
_(last_response.status).must_equal 200
|
||||
@site.reload
|
||||
_(@site.values[:paypal_active]).must_equal false
|
||||
_(@site.paypal_profile_id).must_be_nil
|
||||
_(@site.paypal_token).must_be_nil
|
||||
_(@site.values[:plan_type]).must_equal 'supporter'
|
||||
_(@site.plan_ended).must_equal false
|
||||
_(EmailWorker.jobs.length).must_equal 0
|
||||
end
|
||||
end
|
||||
|
||||
def paypal_supporter_ipn_hash(opts={})
|
||||
{
|
||||
txn_type: 'recurring_payment_profile_cancel',
|
||||
recurring_payment_id: 'I-123'
|
||||
}.merge(opts)
|
||||
end
|
||||
|
||||
def paypal_tip_webhook_hash(opts={})
|
||||
{
|
||||
:transaction_subject=>"customvarlol",
|
||||
|
||||
Reference in New Issue
Block a user