pay 11.8.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/pay/payments_controller.rb +3 -11
- data/app/controllers/pay/webhooks/base_controller.rb +50 -0
- data/app/controllers/pay/webhooks/braintree_controller.rb +11 -18
- data/app/controllers/pay/webhooks/lemon_squeezy_controller.rb +8 -26
- data/app/controllers/pay/webhooks/paddle_billing_controller.rb +13 -35
- data/app/controllers/pay/webhooks/paddle_classic_controller.rb +5 -20
- data/app/controllers/pay/webhooks/stripe_controller.rb +13 -29
- data/app/models/pay/braintree/charge.rb +6 -12
- data/app/models/pay/braintree/payment_method.rb +7 -5
- data/app/models/pay/braintree/subscription.rb +39 -44
- data/app/models/pay/charge.rb +1 -1
- data/app/models/pay/customer.rb +1 -9
- data/app/models/pay/lemon_squeezy/charge.rb +63 -61
- data/app/models/pay/lemon_squeezy/customer.rb +1 -1
- data/app/models/pay/lemon_squeezy/subscription.rb +43 -46
- data/app/models/pay/merchant.rb +1 -1
- data/app/models/pay/paddle_billing/charge.rb +43 -53
- data/app/models/pay/paddle_billing/customer.rb +1 -1
- data/app/models/pay/paddle_billing/payment_method.rb +19 -23
- data/app/models/pay/paddle_billing/subscription.rb +56 -67
- data/app/models/pay/paddle_classic/customer.rb +1 -1
- data/app/models/pay/paddle_classic/subscription.rb +42 -44
- data/app/models/pay/payment_method.rb +1 -5
- data/app/models/pay/stripe/charge.rb +49 -61
- data/app/models/pay/stripe/customer.rb +41 -19
- data/app/models/pay/stripe/payment_method.rb +25 -30
- data/app/models/pay/stripe/subscription.rb +103 -107
- data/app/models/pay/subscription.rb +2 -12
- data/app/views/layouts/pay/application.html.erb +0 -2
- data/app/views/pay/payments/show.html.erb +19 -8
- data/lib/pay/braintree/webhooks/subscription.rb +15 -0
- data/lib/pay/braintree/webhooks/subscription_canceled.rb +1 -7
- data/lib/pay/braintree/webhooks/subscription_expired.rb +1 -7
- data/lib/pay/braintree/webhooks/subscription_trial_ended.rb +1 -7
- data/lib/pay/braintree/webhooks/subscription_went_active.rb +2 -8
- data/lib/pay/braintree/webhooks/subscription_went_past_due.rb +2 -8
- data/lib/pay/braintree.rb +1 -2
- data/lib/pay/currency.rb +0 -4
- data/lib/pay/engine.rb +4 -0
- data/lib/pay/errors.rb +4 -0
- data/lib/pay/lemon_squeezy.rb +4 -7
- data/lib/pay/paddle_billing.rb +4 -1
- data/lib/pay/paddle_classic.rb +4 -1
- data/lib/pay/payment.rb +2 -12
- data/lib/pay/receipts.rb +0 -1
- data/lib/pay/stripe/webhooks/subscription_created.rb +2 -4
- data/lib/pay/stripe/webhooks/subscription_deleted.rb +2 -5
- data/lib/pay/stripe.rb +2 -2
- data/lib/pay/sync.rb +29 -0
- data/lib/pay/version.rb +1 -1
- data/lib/pay.rb +7 -5
- metadata +5 -3
- data/lib/pay/braintree/webhooks/subscription_charged_unsuccessfully.rb +0 -24
data/lib/pay/payment.rb
CHANGED
|
@@ -10,6 +10,8 @@ module Pay
|
|
|
10
10
|
options = {stripe_account: stripe_account}.compact
|
|
11
11
|
intent = id.start_with?("seti_") ? ::Stripe::SetupIntent.retrieve(id, options) : ::Stripe::PaymentIntent.retrieve(id, options)
|
|
12
12
|
new(intent, stripe_account: stripe_account)
|
|
13
|
+
rescue ::Stripe::StripeError => e
|
|
14
|
+
raise Pay::Stripe::Error, e
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def initialize(intent, stripe_account: nil)
|
|
@@ -29,22 +31,10 @@ module Pay
|
|
|
29
31
|
status == "canceled"
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
def cancelled?
|
|
33
|
-
canceled?
|
|
34
|
-
end
|
|
35
|
-
|
|
36
34
|
def succeeded?
|
|
37
35
|
status == "succeeded"
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
def payment_intent?
|
|
41
|
-
intent.is_a?(::Stripe::PaymentIntent)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def setup_intent?
|
|
45
|
-
intent.is_a?(::Stripe::SetupIntent)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
38
|
def amount_with_currency
|
|
49
39
|
Pay::Currency.format(amount, currency: currency)
|
|
50
40
|
end
|
data/lib/pay/receipts.rb
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
module Pay
|
|
2
2
|
module Stripe
|
|
3
3
|
module Webhooks
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Pay::Stripe::Subscription.sync(event.data.object.id, stripe_account: event.try(:account))
|
|
7
|
-
end
|
|
4
|
+
# If a subscription is manually created on Stripe, we want to sync it the same way as an update
|
|
5
|
+
class SubscriptionCreated < SubscriptionUpdated
|
|
8
6
|
end
|
|
9
7
|
end
|
|
10
8
|
end
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
module Pay
|
|
2
2
|
module Stripe
|
|
3
3
|
module Webhooks
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# Canceled subscriptions are still accessible via the API, so we can sync their details
|
|
7
|
-
Pay::Stripe::Subscription.sync(event.data.object.id, stripe_account: event.try(:account))
|
|
8
|
-
end
|
|
4
|
+
# Canceled subscriptions are still accessible via the API, so they sync the same way as an update
|
|
5
|
+
class SubscriptionDeleted < SubscriptionUpdated
|
|
9
6
|
end
|
|
10
7
|
end
|
|
11
8
|
end
|
data/lib/pay/stripe.rb
CHANGED
|
@@ -175,9 +175,9 @@ module Pay
|
|
|
175
175
|
when "subscription"
|
|
176
176
|
Pay::Stripe::Subscription.sync(checkout_session.subscription, stripe_account: stripe_account)
|
|
177
177
|
end
|
|
178
|
-
rescue ::Stripe::InvalidRequestError
|
|
178
|
+
rescue ::Stripe::InvalidRequestError => e
|
|
179
179
|
if try > retries
|
|
180
|
-
raise
|
|
180
|
+
raise Pay::Stripe::Error, e
|
|
181
181
|
else
|
|
182
182
|
try += 1
|
|
183
183
|
sleep 0.15 * try
|
data/lib/pay/sync.rb
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Pay
|
|
2
|
+
# Shared skeleton for the processor Charge.sync, Subscription.sync, and PaymentMethod.sync class methods
|
|
3
|
+
module Sync
|
|
4
|
+
# Runs the sync block, retrying it when a webhook and an API call race to
|
|
5
|
+
# create the same record. The block retrieves the processor's object itself
|
|
6
|
+
# when the caller didn't pass one in, so each retry gets a fresh read.
|
|
7
|
+
def sync_with_retries(retries: 1)
|
|
8
|
+
try = 0
|
|
9
|
+
begin
|
|
10
|
+
yield
|
|
11
|
+
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
|
|
12
|
+
try += 1
|
|
13
|
+
raise if try > retries
|
|
14
|
+
sleep 0.15 * try
|
|
15
|
+
retry
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The Pay::Customer for this processor, or nil when the ID is blank or the customer isn't in the database
|
|
20
|
+
def find_pay_customer(processor_id)
|
|
21
|
+
Pay::Customer.find_by(processor: pay_processor, processor_id: processor_id) if processor_id.present?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# "stripe" for Pay::Stripe::Charge, "paddle_billing" for Pay::PaddleBilling::Subscription, and so on
|
|
25
|
+
def pay_processor
|
|
26
|
+
name.deconstantize.demodulize.underscore
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/pay/version.rb
CHANGED
data/lib/pay.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Pay
|
|
|
12
12
|
autoload :NanoId, "pay/nano_id"
|
|
13
13
|
autoload :Payment, "pay/payment"
|
|
14
14
|
autoload :Receipts, "pay/receipts"
|
|
15
|
+
autoload :Sync, "pay/sync"
|
|
15
16
|
autoload :Currency, "pay/currency"
|
|
16
17
|
|
|
17
18
|
# Payment processors
|
|
@@ -75,15 +76,16 @@ module Pay
|
|
|
75
76
|
@@emails.subscription_trial_will_end = true
|
|
76
77
|
@@emails.subscription_trial_ended = true
|
|
77
78
|
|
|
79
|
+
mattr_writer :mailer
|
|
78
80
|
@@mailer = "Pay::UserMailer"
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
@@
|
|
82
|
+
# Resolved on every call rather than memoized, so code reloading in development returns the current class
|
|
83
|
+
def self.mailer
|
|
84
|
+
@@mailer.constantize
|
|
83
85
|
end
|
|
84
86
|
|
|
85
|
-
def self.
|
|
86
|
-
|
|
87
|
+
def self.deprecator
|
|
88
|
+
@deprecator ||= ActiveSupport::Deprecation.new("13.0", "Pay")
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
mattr_accessor :parent_mailer
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pay
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 12.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jason Charnes
|
|
@@ -42,6 +42,7 @@ files:
|
|
|
42
42
|
- app/assets/stylesheets/pay/application.css
|
|
43
43
|
- app/controllers/pay/application_controller.rb
|
|
44
44
|
- app/controllers/pay/payments_controller.rb
|
|
45
|
+
- app/controllers/pay/webhooks/base_controller.rb
|
|
45
46
|
- app/controllers/pay/webhooks/braintree_controller.rb
|
|
46
47
|
- app/controllers/pay/webhooks/lemon_squeezy_controller.rb
|
|
47
48
|
- app/controllers/pay/webhooks/paddle_billing_controller.rb
|
|
@@ -115,9 +116,9 @@ files:
|
|
|
115
116
|
- lib/pay/attributes.rb
|
|
116
117
|
- lib/pay/billable/sync_customer.rb
|
|
117
118
|
- lib/pay/braintree.rb
|
|
119
|
+
- lib/pay/braintree/webhooks/subscription.rb
|
|
118
120
|
- lib/pay/braintree/webhooks/subscription_canceled.rb
|
|
119
121
|
- lib/pay/braintree/webhooks/subscription_charged_successfully.rb
|
|
120
|
-
- lib/pay/braintree/webhooks/subscription_charged_unsuccessfully.rb
|
|
121
122
|
- lib/pay/braintree/webhooks/subscription_expired.rb
|
|
122
123
|
- lib/pay/braintree/webhooks/subscription_trial_ended.rb
|
|
123
124
|
- lib/pay/braintree/webhooks/subscription_went_active.rb
|
|
@@ -165,6 +166,7 @@ files:
|
|
|
165
166
|
- lib/pay/stripe/webhooks/subscription_renewing.rb
|
|
166
167
|
- lib/pay/stripe/webhooks/subscription_trial_will_end.rb
|
|
167
168
|
- lib/pay/stripe/webhooks/subscription_updated.rb
|
|
169
|
+
- lib/pay/sync.rb
|
|
168
170
|
- lib/pay/version.rb
|
|
169
171
|
- lib/pay/webhooks.rb
|
|
170
172
|
- lib/pay/webhooks/delegator.rb
|
|
@@ -189,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
189
191
|
- !ruby/object:Gem::Version
|
|
190
192
|
version: '0'
|
|
191
193
|
requirements: []
|
|
192
|
-
rubygems_version: 4.0.
|
|
194
|
+
rubygems_version: 4.0.21
|
|
193
195
|
specification_version: 4
|
|
194
196
|
summary: Payments engine for Ruby on Rails
|
|
195
197
|
test_files: []
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# A subscription successfully moves to the next billing cycle. This will also occur when either a new transaction is created mid-cycle due to proration on an upgrade or a billing cycle is skipped due to the presence of a negative balance that covers the cost of the subscription.
|
|
2
|
-
|
|
3
|
-
module Pay
|
|
4
|
-
module Braintree
|
|
5
|
-
module Webhooks
|
|
6
|
-
class SubscriptionChargedUnsuccessfully
|
|
7
|
-
def call(event)
|
|
8
|
-
# subscription = event.subscription
|
|
9
|
-
# return if subscription.nil?
|
|
10
|
-
|
|
11
|
-
# pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
|
12
|
-
# return unless pay_subscription.present?
|
|
13
|
-
|
|
14
|
-
# pay_customer = pay_subscription.customer
|
|
15
|
-
# pay_charge = Pay::Braintree::Billable.new(pay_customer).save_transaction(subscription.transactions.first)
|
|
16
|
-
|
|
17
|
-
# if Pay.send_emails
|
|
18
|
-
# Pay.mailer.with(pay_customer: pay_charge.customer, charge: pay_charge).receipt.deliver_later
|
|
19
|
-
# end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|