pay 2.6.7 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pay might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/app/models/pay.rb +5 -0
- data/app/models/pay/charge.rb +2 -0
- data/app/models/pay/subscription.rb +9 -2
- data/app/views/pay/stripe/_checkout_button.html.erb +1 -1
- data/db/migrate/20200603134434_add_data_to_pay_models.rb +2 -9
- data/db/migrate/20210309004259_add_data_to_pay_billable.rb +19 -0
- data/db/migrate/20210406215234_add_currency_to_pay_charges.rb +5 -0
- data/db/migrate/20210406215506_add_application_fee_to_pay_models.rb +7 -0
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/lib/pay.rb +22 -0
- data/lib/pay/adapter.rb +13 -0
- data/lib/pay/billable.rb +4 -0
- data/lib/pay/braintree/billable.rb +11 -2
- data/lib/pay/braintree/subscription.rb +4 -0
- data/lib/pay/fake_processor/subscription.rb +4 -0
- data/lib/pay/merchant.rb +37 -0
- data/lib/pay/paddle.rb +7 -0
- data/lib/pay/paddle/subscription.rb +7 -0
- data/lib/pay/paddle/webhooks/subscription_created.rb +1 -10
- data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +14 -2
- data/lib/pay/stripe.rb +5 -0
- data/lib/pay/stripe/billable.rb +46 -34
- data/lib/pay/stripe/charge.rb +9 -4
- data/lib/pay/stripe/merchant.rb +66 -0
- data/lib/pay/stripe/subscription.rb +35 -20
- data/lib/pay/stripe/webhooks/account_updated.rb +17 -0
- data/lib/pay/stripe/webhooks/subscription_created.rb +2 -1
- data/lib/pay/stripe/webhooks/subscription_updated.rb +3 -2
- data/lib/pay/version.rb +1 -1
- metadata +11 -17
- data/lib/pay/stripe_marketplace/billable.rb +0 -246
- data/lib/pay/stripe_marketplace/charge.rb +0 -26
- data/lib/pay/stripe_marketplace/error.rb +0 -9
- data/lib/pay/stripe_marketplace/subscription.rb +0 -83
- data/lib/pay/stripe_marketplace/webhooks/charge_refunded.rb +0 -23
- data/lib/pay/stripe_marketplace/webhooks/charge_succeeded.rb +0 -24
- data/lib/pay/stripe_marketplace/webhooks/customer_deleted.rb +0 -29
- data/lib/pay/stripe_marketplace/webhooks/customer_updated.rb +0 -17
- data/lib/pay/stripe_marketplace/webhooks/payment_action_required.rb +0 -26
- data/lib/pay/stripe_marketplace/webhooks/payment_method_updated.rb +0 -17
- data/lib/pay/stripe_marketplace/webhooks/subscription_created.rb +0 -45
- data/lib/pay/stripe_marketplace/webhooks/subscription_deleted.rb +0 -19
- data/lib/pay/stripe_marketplace/webhooks/subscription_renewing.rb +0 -24
- data/lib/pay/stripe_marketplace/webhooks/subscription_updated.rb +0 -38
data/lib/pay/stripe/charge.rb
CHANGED
@@ -3,20 +3,25 @@ module Pay
|
|
3
3
|
class Charge
|
4
4
|
attr_reader :pay_charge
|
5
5
|
|
6
|
-
delegate :processor_id, :owner, to: :pay_charge
|
6
|
+
delegate :processor_id, :owner, :stripe_account, to: :pay_charge
|
7
7
|
|
8
8
|
def initialize(pay_charge)
|
9
9
|
@pay_charge = pay_charge
|
10
10
|
end
|
11
11
|
|
12
12
|
def charge
|
13
|
-
::Stripe::Charge.retrieve(processor_id)
|
13
|
+
::Stripe::Charge.retrieve({id: processor_id, expand: ["customer", "invoice.subscription"]}, {stripe_account: stripe_account})
|
14
14
|
rescue ::Stripe::StripeError => e
|
15
15
|
raise Pay::Stripe::Error, e
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
# https://stripe.com/docs/api/refunds/create
|
19
|
+
#
|
20
|
+
# refund!
|
21
|
+
# refund!(5_00)
|
22
|
+
# refund!(5_00, refund_application_fee: true)
|
23
|
+
def refund!(amount_to_refund, **options)
|
24
|
+
::Stripe::Refund.create(options.merge(charge: processor_id, amount: amount_to_refund), {stripe_account: stripe_account})
|
20
25
|
pay_charge.update(amount_refunded: amount_to_refund)
|
21
26
|
rescue ::Stripe::StripeError => e
|
22
27
|
raise Pay::Stripe::Error, e
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Pay
|
2
|
+
module Stripe
|
3
|
+
class Merchant
|
4
|
+
attr_reader :merchant
|
5
|
+
|
6
|
+
delegate :stripe_connect_account_id,
|
7
|
+
to: :merchant
|
8
|
+
|
9
|
+
def initialize(merchant)
|
10
|
+
@merchant = merchant
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_account(**options)
|
14
|
+
defaults = {
|
15
|
+
type: "express",
|
16
|
+
capabilities: {
|
17
|
+
card_payments: {requested: true},
|
18
|
+
transfers: {requested: true}
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
stripe_account = ::Stripe::Account.create(defaults.merge(options))
|
23
|
+
merchant.update(stripe_connect_account_id: stripe_account.id)
|
24
|
+
stripe_account
|
25
|
+
rescue ::Stripe::StripeError => e
|
26
|
+
raise Pay::Stripe::Error, e
|
27
|
+
end
|
28
|
+
|
29
|
+
def account
|
30
|
+
::Stripe::Account.retrieve(stripe_connect_account_id)
|
31
|
+
rescue ::Stripe::StripeError => e
|
32
|
+
raise Pay::Stripe::Error, e
|
33
|
+
end
|
34
|
+
|
35
|
+
def account_link(refresh_url:, return_url:, type: "account_onboarding", **options)
|
36
|
+
::Stripe::AccountLink.create({
|
37
|
+
account: stripe_connect_account_id,
|
38
|
+
refresh_url: refresh_url,
|
39
|
+
return_url: return_url,
|
40
|
+
type: type
|
41
|
+
})
|
42
|
+
rescue ::Stripe::StripeError => e
|
43
|
+
raise Pay::Stripe::Error, e
|
44
|
+
end
|
45
|
+
|
46
|
+
# A single-use login link for Express accounts to access their Stripe dashboard
|
47
|
+
def login_link(**options)
|
48
|
+
::Stripe::Account.create_login_link(stripe_connect_account_id)
|
49
|
+
rescue ::Stripe::StripeError => e
|
50
|
+
raise Pay::Stripe::Error, e
|
51
|
+
end
|
52
|
+
|
53
|
+
# Transfer money from the platform to this connected account
|
54
|
+
# https://stripe.com/docs/connect/charges-transfers#transfer-availability
|
55
|
+
def transfer(amount:, currency: "usd", **options)
|
56
|
+
::Stripe::Transfer.create({
|
57
|
+
amount: amount,
|
58
|
+
currency: currency,
|
59
|
+
destination: stripe_connect_account_id
|
60
|
+
}.merge(options))
|
61
|
+
rescue ::Stripe::StripeError => e
|
62
|
+
raise Pay::Stripe::Error, e
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -16,6 +16,7 @@ module Pay
|
|
16
16
|
:prorate?,
|
17
17
|
:quantity,
|
18
18
|
:quantity?,
|
19
|
+
:stripe_account,
|
19
20
|
:trial_ends_at,
|
20
21
|
to: :pay_subscription
|
21
22
|
|
@@ -23,20 +24,26 @@ module Pay
|
|
23
24
|
@pay_subscription = pay_subscription
|
24
25
|
end
|
25
26
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
subscription.save
|
27
|
+
def subscription(**options)
|
28
|
+
::Stripe::Subscription.retrieve(options.merge(id: processor_id))
|
29
|
+
end
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
def cancel
|
32
|
+
stripe_sub = ::Stripe::Subscription.update(processor_id, {cancel_at_period_end: true}, {stripe_account: stripe_account})
|
33
|
+
pay_subscription.update(ends_at: (on_trial? ? trial_ends_at : Time.at(stripe_sub.current_period_end)))
|
33
34
|
rescue ::Stripe::StripeError => e
|
34
35
|
raise Pay::Stripe::Error, e
|
35
36
|
end
|
36
37
|
|
37
38
|
def cancel_now!
|
38
|
-
|
39
|
-
pay_subscription.update(ends_at: Time.
|
39
|
+
::Stripe::Subscription.delete(processor_id, {stripe_account: stripe_account})
|
40
|
+
pay_subscription.update(ends_at: Time.current, status: :canceled)
|
41
|
+
rescue ::Stripe::StripeError => e
|
42
|
+
raise Pay::Stripe::Error, e
|
43
|
+
end
|
44
|
+
|
45
|
+
def change_quantity(quantity)
|
46
|
+
::Stripe::Subscription.update(processor_id, quantity: quantity)
|
40
47
|
rescue ::Stripe::StripeError => e
|
41
48
|
raise Pay::Stripe::Error, e
|
42
49
|
end
|
@@ -58,23 +65,31 @@ module Pay
|
|
58
65
|
raise StandardError, "You can only resume subscriptions within their grace period."
|
59
66
|
end
|
60
67
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
68
|
+
::Stripe::Subscription.update(
|
69
|
+
processor_id,
|
70
|
+
{
|
71
|
+
plan: processor_plan,
|
72
|
+
trial_end: (on_trial? ? trial_ends_at.to_i : "now"),
|
73
|
+
cancel_at_period_end: false
|
74
|
+
},
|
75
|
+
{stripe_account: stripe_account}
|
76
|
+
)
|
66
77
|
rescue ::Stripe::StripeError => e
|
67
78
|
raise Pay::Stripe::Error, e
|
68
79
|
end
|
69
80
|
|
70
81
|
def swap(plan)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
82
|
+
::Stripe::Subscription.update(
|
83
|
+
processor_id,
|
84
|
+
{
|
85
|
+
cancel_at_period_end: false,
|
86
|
+
plan: plan,
|
87
|
+
proration_behavior: (prorate ? "create_prorations" : "none"),
|
88
|
+
trial_end: (on_trial? ? trial_ends_at.to_i : "now"),
|
89
|
+
quantity: quantity
|
90
|
+
},
|
91
|
+
{stripe_account: stripe_account}
|
92
|
+
)
|
78
93
|
rescue ::Stripe::StripeError => e
|
79
94
|
raise Pay::Stripe::Error, e
|
80
95
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Pay
|
2
|
+
module Stripe
|
3
|
+
module Webhooks
|
4
|
+
class AccountUpdated
|
5
|
+
def call(event)
|
6
|
+
object = event.data.object
|
7
|
+
|
8
|
+
merchant = Pay.find_merchant("stripe_connect_account_id", object.id)
|
9
|
+
|
10
|
+
return unless merchant.present?
|
11
|
+
|
12
|
+
merchant.update(onboarding_complete: object.charges_enabled)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -21,9 +21,10 @@ module Pay
|
|
21
21
|
subscription = Pay.subscription_model.new(name: Pay.default_product_name, owner: owner, processor: :stripe, processor_id: object.id)
|
22
22
|
end
|
23
23
|
|
24
|
+
subscription.application_fee_percent = object.application_fee_percent
|
25
|
+
subscription.processor_plan = object.plan.id
|
24
26
|
subscription.quantity = object.quantity
|
25
27
|
subscription.status = object.status
|
26
|
-
subscription.processor_plan = object.plan.id
|
27
28
|
subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
|
28
29
|
|
29
30
|
# If user was on trial, their subscription ends at the end of the trial
|
@@ -14,9 +14,10 @@ module Pay
|
|
14
14
|
return
|
15
15
|
end
|
16
16
|
|
17
|
-
subscription.
|
18
|
-
subscription.quantity = object.quantity
|
17
|
+
subscription.application_fee_percent = object.application_fee_percent
|
19
18
|
subscription.processor_plan = object.plan.id
|
19
|
+
subscription.quantity = object.quantity
|
20
|
+
subscription.status = object.status
|
20
21
|
subscription.trial_ends_at = Time.at(object.trial_end) if object.trial_end.present?
|
21
22
|
|
22
23
|
# If user was on trial, their subscription ends at the end of the trial
|
data/lib/pay/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Charnes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-05-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- app/jobs/pay/email_sync_job.rb
|
126
126
|
- app/mailers/pay/application_mailer.rb
|
127
127
|
- app/mailers/pay/user_mailer.rb
|
128
|
+
- app/models/pay.rb
|
128
129
|
- app/models/pay/application_record.rb
|
129
130
|
- app/models/pay/charge.rb
|
130
131
|
- app/models/pay/subscription.rb
|
@@ -141,6 +142,9 @@ files:
|
|
141
142
|
- db/migrate/20170727235816_create_pay_charges.rb
|
142
143
|
- db/migrate/20190816015720_add_status_to_pay_subscriptions.rb
|
143
144
|
- db/migrate/20200603134434_add_data_to_pay_models.rb
|
145
|
+
- db/migrate/20210309004259_add_data_to_pay_billable.rb
|
146
|
+
- db/migrate/20210406215234_add_currency_to_pay_charges.rb
|
147
|
+
- db/migrate/20210406215506_add_application_fee_to_pay_models.rb
|
144
148
|
- lib/generators/active_record/pay_generator.rb
|
145
149
|
- lib/generators/active_record/templates/migration.rb
|
146
150
|
- lib/generators/pay/email_views_generator.rb
|
@@ -148,6 +152,7 @@ files:
|
|
148
152
|
- lib/generators/pay/pay_generator.rb
|
149
153
|
- lib/generators/pay/views_generator.rb
|
150
154
|
- lib/pay.rb
|
155
|
+
- lib/pay/adapter.rb
|
151
156
|
- lib/pay/billable.rb
|
152
157
|
- lib/pay/billable/sync_email.rb
|
153
158
|
- lib/pay/braintree.rb
|
@@ -171,6 +176,7 @@ files:
|
|
171
176
|
- lib/pay/fake_processor/charge.rb
|
172
177
|
- lib/pay/fake_processor/error.rb
|
173
178
|
- lib/pay/fake_processor/subscription.rb
|
179
|
+
- lib/pay/merchant.rb
|
174
180
|
- lib/pay/paddle.rb
|
175
181
|
- lib/pay/paddle/billable.rb
|
176
182
|
- lib/pay/paddle/charge.rb
|
@@ -188,7 +194,9 @@ files:
|
|
188
194
|
- lib/pay/stripe/billable.rb
|
189
195
|
- lib/pay/stripe/charge.rb
|
190
196
|
- lib/pay/stripe/error.rb
|
197
|
+
- lib/pay/stripe/merchant.rb
|
191
198
|
- lib/pay/stripe/subscription.rb
|
199
|
+
- lib/pay/stripe/webhooks/account_updated.rb
|
192
200
|
- lib/pay/stripe/webhooks/charge_refunded.rb
|
193
201
|
- lib/pay/stripe/webhooks/charge_succeeded.rb
|
194
202
|
- lib/pay/stripe/webhooks/customer_deleted.rb
|
@@ -200,20 +208,6 @@ files:
|
|
200
208
|
- lib/pay/stripe/webhooks/subscription_deleted.rb
|
201
209
|
- lib/pay/stripe/webhooks/subscription_renewing.rb
|
202
210
|
- lib/pay/stripe/webhooks/subscription_updated.rb
|
203
|
-
- lib/pay/stripe_marketplace/billable.rb
|
204
|
-
- lib/pay/stripe_marketplace/charge.rb
|
205
|
-
- lib/pay/stripe_marketplace/error.rb
|
206
|
-
- lib/pay/stripe_marketplace/subscription.rb
|
207
|
-
- lib/pay/stripe_marketplace/webhooks/charge_refunded.rb
|
208
|
-
- lib/pay/stripe_marketplace/webhooks/charge_succeeded.rb
|
209
|
-
- lib/pay/stripe_marketplace/webhooks/customer_deleted.rb
|
210
|
-
- lib/pay/stripe_marketplace/webhooks/customer_updated.rb
|
211
|
-
- lib/pay/stripe_marketplace/webhooks/payment_action_required.rb
|
212
|
-
- lib/pay/stripe_marketplace/webhooks/payment_method_updated.rb
|
213
|
-
- lib/pay/stripe_marketplace/webhooks/subscription_created.rb
|
214
|
-
- lib/pay/stripe_marketplace/webhooks/subscription_deleted.rb
|
215
|
-
- lib/pay/stripe_marketplace/webhooks/subscription_renewing.rb
|
216
|
-
- lib/pay/stripe_marketplace/webhooks/subscription_updated.rb
|
217
211
|
- lib/pay/version.rb
|
218
212
|
- lib/pay/webhooks.rb
|
219
213
|
- lib/pay/webhooks/delegator.rb
|
@@ -236,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
230
|
- !ruby/object:Gem::Version
|
237
231
|
version: '0'
|
238
232
|
requirements: []
|
239
|
-
rubygems_version: 3.2.
|
233
|
+
rubygems_version: 3.2.15
|
240
234
|
signing_key:
|
241
235
|
specification_version: 4
|
242
236
|
summary: Payments engine for Ruby on Rails
|
@@ -1,246 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module StripeMarketplace
|
3
|
-
class Billable
|
4
|
-
include Rails.application.routes.url_helpers
|
5
|
-
|
6
|
-
attr_reader :billable
|
7
|
-
|
8
|
-
delegate :processor_id,
|
9
|
-
:processor_id?,
|
10
|
-
:email,
|
11
|
-
:customer_name,
|
12
|
-
:card_token,
|
13
|
-
to: :billable
|
14
|
-
|
15
|
-
class << self
|
16
|
-
def default_url_options
|
17
|
-
Rails.application.config.action_mailer.default_url_options || {}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def initialize(billable)
|
22
|
-
@billable = billable
|
23
|
-
end
|
24
|
-
|
25
|
-
# Handles Billable#customer
|
26
|
-
#
|
27
|
-
# Returns Stripe::Customer
|
28
|
-
def customer
|
29
|
-
if processor_id?
|
30
|
-
::Stripe::Customer.retrieve(processor_id)
|
31
|
-
else
|
32
|
-
stripe_customer = ::Stripe::Customer.create(email: email, name: customer_name)
|
33
|
-
billable.update(processor: :stripe, processor_id: stripe_customer.id)
|
34
|
-
|
35
|
-
# Update the user's card on file if a token was passed in
|
36
|
-
if card_token.present?
|
37
|
-
payment_method = ::Stripe::PaymentMethod.attach(card_token, {customer: stripe_customer.id})
|
38
|
-
stripe_customer.invoice_settings.default_payment_method = payment_method.id
|
39
|
-
stripe_customer.save
|
40
|
-
|
41
|
-
update_card_on_file ::Stripe::PaymentMethod.retrieve(card_token).card
|
42
|
-
end
|
43
|
-
|
44
|
-
stripe_customer
|
45
|
-
end
|
46
|
-
rescue ::Stripe::StripeError => e
|
47
|
-
raise Pay::Stripe::Error, e
|
48
|
-
end
|
49
|
-
|
50
|
-
# Handles Billable#charge
|
51
|
-
#
|
52
|
-
# Returns Pay::Charge
|
53
|
-
def charge(amount, options = {})
|
54
|
-
stripe_customer = customer
|
55
|
-
args = {
|
56
|
-
amount: amount,
|
57
|
-
confirm: true,
|
58
|
-
confirmation_method: :automatic,
|
59
|
-
currency: "usd",
|
60
|
-
customer: stripe_customer.id,
|
61
|
-
payment_method: stripe_customer.invoice_settings.default_payment_method
|
62
|
-
}.merge(options)
|
63
|
-
|
64
|
-
payment_intent = ::Stripe::PaymentIntent.create(args)
|
65
|
-
Pay::Payment.new(payment_intent).validate
|
66
|
-
|
67
|
-
# Create a new charge object
|
68
|
-
save_pay_charge(payment_intent.charges.first)
|
69
|
-
rescue ::Stripe::StripeError => e
|
70
|
-
raise Pay::Stripe::Error, e
|
71
|
-
end
|
72
|
-
|
73
|
-
# Handles Billable#subscribe
|
74
|
-
#
|
75
|
-
# Returns Pay::Subscription
|
76
|
-
def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
|
77
|
-
quantity = options.delete(:quantity) || 1
|
78
|
-
opts = {
|
79
|
-
expand: ["pending_setup_intent", "latest_invoice.payment_intent"],
|
80
|
-
items: [plan: plan, quantity: quantity],
|
81
|
-
off_session: true
|
82
|
-
}.merge(options)
|
83
|
-
|
84
|
-
# Inherit trial from plan unless trial override was specified
|
85
|
-
opts[:trial_from_plan] = true unless opts[:trial_period_days]
|
86
|
-
|
87
|
-
opts[:customer] = customer.id
|
88
|
-
|
89
|
-
stripe_sub = ::Stripe::Subscription.create(opts)
|
90
|
-
subscription = billable.create_pay_subscription(stripe_sub, "stripe", name, plan, status: stripe_sub.status, quantity: quantity)
|
91
|
-
|
92
|
-
# No trial, card requires SCA
|
93
|
-
if subscription.incomplete?
|
94
|
-
Pay::Payment.new(stripe_sub.latest_invoice.payment_intent).validate
|
95
|
-
|
96
|
-
# Trial, card requires SCA
|
97
|
-
elsif subscription.on_trial? && stripe_sub.pending_setup_intent
|
98
|
-
Pay::Payment.new(stripe_sub.pending_setup_intent).validate
|
99
|
-
end
|
100
|
-
|
101
|
-
subscription
|
102
|
-
rescue ::Stripe::StripeError => e
|
103
|
-
raise Pay::Stripe::Error, e
|
104
|
-
end
|
105
|
-
|
106
|
-
# Handles Billable#update_card
|
107
|
-
#
|
108
|
-
# Returns true if successful
|
109
|
-
def update_card(payment_method_id)
|
110
|
-
stripe_customer = customer
|
111
|
-
|
112
|
-
return true if payment_method_id == stripe_customer.invoice_settings.default_payment_method
|
113
|
-
|
114
|
-
payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, customer: stripe_customer.id)
|
115
|
-
::Stripe::Customer.update(stripe_customer.id, invoice_settings: {default_payment_method: payment_method.id})
|
116
|
-
|
117
|
-
update_card_on_file(payment_method.card)
|
118
|
-
true
|
119
|
-
rescue ::Stripe::StripeError => e
|
120
|
-
raise Pay::Stripe::Error, e
|
121
|
-
end
|
122
|
-
|
123
|
-
def update_email!
|
124
|
-
::Stripe::Customer.update(processor_id, {email: email, name: customer_name})
|
125
|
-
end
|
126
|
-
|
127
|
-
def processor_subscription(subscription_id, options = {})
|
128
|
-
::Stripe::Subscription.retrieve(options.merge(id: subscription_id))
|
129
|
-
end
|
130
|
-
|
131
|
-
def invoice!(options = {})
|
132
|
-
return unless processor_id?
|
133
|
-
::Stripe::Invoice.create(options.merge(customer: processor_id)).pay
|
134
|
-
end
|
135
|
-
|
136
|
-
def upcoming_invoice
|
137
|
-
::Stripe::Invoice.upcoming(customer: processor_id)
|
138
|
-
end
|
139
|
-
|
140
|
-
# Used by webhooks when the customer or source changes
|
141
|
-
def sync_card_from_stripe
|
142
|
-
if (payment_method_id = customer.invoice_settings.default_payment_method)
|
143
|
-
update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id).card
|
144
|
-
else
|
145
|
-
billable.update(card_type: nil, card_last4: nil)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def create_setup_intent
|
150
|
-
::Stripe::SetupIntent.create(customer: processor_id, usage: :off_session)
|
151
|
-
end
|
152
|
-
|
153
|
-
def trial_end_date(stripe_sub)
|
154
|
-
# Times in Stripe are returned in UTC
|
155
|
-
stripe_sub.trial_end.present? ? Time.at(stripe_sub.trial_end) : nil
|
156
|
-
end
|
157
|
-
|
158
|
-
# Save the card to the database as the user's current card
|
159
|
-
def update_card_on_file(card)
|
160
|
-
billable.update!(
|
161
|
-
card_type: card.brand.capitalize,
|
162
|
-
card_last4: card.last4,
|
163
|
-
card_exp_month: card.exp_month,
|
164
|
-
card_exp_year: card.exp_year
|
165
|
-
)
|
166
|
-
|
167
|
-
billable.card_token = nil
|
168
|
-
end
|
169
|
-
|
170
|
-
def save_pay_charge(object)
|
171
|
-
charge = billable.charges.find_or_initialize_by(processor: :stripe, processor_id: object.id)
|
172
|
-
|
173
|
-
charge.update(
|
174
|
-
amount: object.amount,
|
175
|
-
card_last4: object.payment_method_details.card.last4,
|
176
|
-
card_type: object.payment_method_details.card.brand,
|
177
|
-
card_exp_month: object.payment_method_details.card.exp_month,
|
178
|
-
card_exp_year: object.payment_method_details.card.exp_year,
|
179
|
-
created_at: Time.zone.at(object.created)
|
180
|
-
)
|
181
|
-
|
182
|
-
charge
|
183
|
-
end
|
184
|
-
|
185
|
-
# https://stripe.com/docs/api/checkout/sessions/create
|
186
|
-
#
|
187
|
-
# checkout(mode: "payment")
|
188
|
-
# checkout(mode: "setup")
|
189
|
-
# checkout(mode: "subscription")
|
190
|
-
#
|
191
|
-
# checkout(line_items: "price_12345", quantity: 2)
|
192
|
-
# checkout(line_items [{ price: "price_123" }, { price: "price_456" }])
|
193
|
-
# checkout(line_items, "price_12345", allow_promotion_codes: true)
|
194
|
-
#
|
195
|
-
def checkout(**options)
|
196
|
-
args = {
|
197
|
-
customer: processor_id,
|
198
|
-
payment_method_types: ["card"],
|
199
|
-
mode: "payment",
|
200
|
-
# These placeholder URLs will be replaced in a following step.
|
201
|
-
success_url: root_url,
|
202
|
-
cancel_url: root_url
|
203
|
-
}
|
204
|
-
|
205
|
-
# Line items are optional
|
206
|
-
if (line_items = options.delete(:line_items))
|
207
|
-
args[:line_items] = Array.wrap(line_items).map { |item|
|
208
|
-
if item.is_a? Hash
|
209
|
-
item
|
210
|
-
else
|
211
|
-
{price: item, quantity: options.fetch(:quantity, 1)}
|
212
|
-
end
|
213
|
-
}
|
214
|
-
end
|
215
|
-
|
216
|
-
::Stripe::Checkout::Session.create(args.merge(options))
|
217
|
-
end
|
218
|
-
|
219
|
-
# https://stripe.com/docs/api/checkout/sessions/create
|
220
|
-
#
|
221
|
-
# checkout_charge(amount: 15_00, name: "T-shirt", quantity: 2)
|
222
|
-
#
|
223
|
-
def checkout_charge(amount:, name:, quantity: 1, **options)
|
224
|
-
checkout(
|
225
|
-
line_items: {
|
226
|
-
price_data: {
|
227
|
-
currency: options[:currency] || "usd",
|
228
|
-
product_data: {name: name},
|
229
|
-
unit_amount: amount
|
230
|
-
},
|
231
|
-
quantity: quantity
|
232
|
-
},
|
233
|
-
**options
|
234
|
-
)
|
235
|
-
end
|
236
|
-
|
237
|
-
def billing_portal(**options)
|
238
|
-
args = {
|
239
|
-
customer: processor_id,
|
240
|
-
return_url: options[:return_url] || root_url
|
241
|
-
}
|
242
|
-
::Stripe::BillingPortal::Session.create(args.merge(options))
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|