pay 2.6.10 → 2.7.2
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 +93 -54
- data/app/models/pay/application_record.rb +1 -0
- data/app/models/pay/charge.rb +3 -1
- data/app/models/pay/subscription.rb +5 -3
- data/db/migrate/20200603134434_add_data_to_pay_models.rb +2 -18
- data/db/migrate/20210309004259_add_data_to_pay_billable.rb +10 -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/db/migrate/20210714175351_add_uniqueness_to_pay_models.rb +6 -0
- data/lib/generators/active_record/billable_generator.rb +44 -0
- data/lib/generators/active_record/merchant_generator.rb +44 -0
- data/lib/generators/active_record/templates/billable_migration.rb +17 -0
- data/lib/generators/active_record/templates/merchant_migration.rb +12 -0
- data/lib/generators/pay/{pay_generator.rb → billable_generator.rb} +2 -3
- data/lib/generators/pay/merchant_generator.rb +17 -0
- data/lib/generators/pay/orm_helpers.rb +10 -6
- data/lib/pay.rb +22 -0
- data/lib/pay/adapter.rb +22 -0
- data/lib/pay/billable.rb +4 -0
- data/lib/pay/braintree/billable.rb +8 -1
- data/lib/pay/braintree/subscription.rb +6 -0
- data/lib/pay/env.rb +8 -0
- data/lib/pay/fake_processor/subscription.rb +6 -0
- data/lib/pay/merchant.rb +37 -0
- data/lib/pay/paddle/subscription.rb +9 -0
- data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +3 -1
- data/lib/pay/stripe.rb +11 -0
- data/lib/pay/stripe/billable.rb +39 -36
- data/lib/pay/stripe/charge.rb +62 -4
- data/lib/pay/stripe/merchant.rb +66 -0
- data/lib/pay/stripe/subscription.rb +87 -21
- data/lib/pay/stripe/webhooks/account_updated.rb +17 -0
- data/lib/pay/stripe/webhooks/charge_refunded.rb +2 -7
- data/lib/pay/stripe/webhooks/charge_succeeded.rb +2 -8
- data/lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb +13 -0
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +13 -0
- data/lib/pay/stripe/webhooks/payment_intent_succeeded.rb +2 -8
- data/lib/pay/stripe/webhooks/payment_method_attached.rb +17 -0
- data/lib/pay/stripe/webhooks/payment_method_automatically_updated.rb +17 -0
- data/lib/pay/stripe/webhooks/payment_method_detached.rb +17 -0
- data/lib/pay/stripe/webhooks/subscription_created.rb +1 -35
- data/lib/pay/stripe/webhooks/subscription_deleted.rb +1 -9
- data/lib/pay/stripe/webhooks/subscription_renewing.rb +4 -6
- data/lib/pay/stripe/webhooks/subscription_updated.rb +1 -28
- data/lib/pay/version.rb +1 -1
- metadata +22 -6
- data/lib/generators/active_record/pay_generator.rb +0 -58
- data/lib/generators/active_record/templates/migration.rb +0 -9
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPayBillableTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
def change
|
5
|
+
change_table :<%= table_name %>, bulk: true do |t|
|
6
|
+
t.string :processor
|
7
|
+
t.string :processor_id
|
8
|
+
t.public_send(Pay::Adapter.json_column_type, :pay_data)
|
9
|
+
t.datetime :trial_ends_at
|
10
|
+
t.string :card_type
|
11
|
+
t.string :card_last4
|
12
|
+
t.string :card_exp_month
|
13
|
+
t.string :card_exp_year
|
14
|
+
t.text :extra_billing_info
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPayMerchantTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
def change
|
5
|
+
add_column table_name, :merchant_processor, :string
|
6
|
+
|
7
|
+
# We may already have the pay_data column if a Pay::Billable object is also a Pay::Merchant
|
8
|
+
unless ActiveRecord::Base.connection.column_exists?(table_name, :pay_data)
|
9
|
+
add_column :<%= table_name %>, :pay_data, Pay::Adapter.json_column_type
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -4,13 +4,12 @@ require "rails/generators/named_base"
|
|
4
4
|
|
5
5
|
module Pay
|
6
6
|
module Generators
|
7
|
-
class
|
7
|
+
class BillableGenerator < Rails::Generators::NamedBase
|
8
8
|
include Rails::Generators::ResourceHelpers
|
9
9
|
|
10
|
-
namespace "pay"
|
11
10
|
source_root File.expand_path("../templates", __FILE__)
|
12
11
|
|
13
|
-
desc "Generates a migration to add Billable fields to a model."
|
12
|
+
desc "Generates a migration to add Pay::Billable fields to a model."
|
14
13
|
|
15
14
|
hook_for :orm
|
16
15
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/named_base"
|
4
|
+
|
5
|
+
module Pay
|
6
|
+
module Generators
|
7
|
+
class MerchantGenerator < Rails::Generators::NamedBase
|
8
|
+
include Rails::Generators::ResourceHelpers
|
9
|
+
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
desc "Generates a migration to add Pay::Merchant fields to a model."
|
13
|
+
|
14
|
+
hook_for :orm
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -3,12 +3,6 @@
|
|
3
3
|
module Pay
|
4
4
|
module Generators
|
5
5
|
module OrmHelpers
|
6
|
-
def model_contents
|
7
|
-
<<-CONTENT
|
8
|
-
include Pay::Billable
|
9
|
-
CONTENT
|
10
|
-
end
|
11
|
-
|
12
6
|
private
|
13
7
|
|
14
8
|
def model_exists?
|
@@ -30,6 +24,16 @@ module Pay
|
|
30
24
|
def model_path
|
31
25
|
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
32
26
|
end
|
27
|
+
|
28
|
+
def migration_version
|
29
|
+
if rails5_and_up?
|
30
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def rails5_and_up?
|
35
|
+
Rails::VERSION::MAJOR >= 5
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
data/lib/pay.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require "pay/version"
|
2
2
|
require "pay/engine"
|
3
3
|
require "pay/errors"
|
4
|
+
require "pay/adapter"
|
4
5
|
|
5
6
|
module Pay
|
6
7
|
autoload :Billable, "pay/billable"
|
7
8
|
autoload :Env, "pay/env"
|
9
|
+
autoload :Merchant, "pay/merchant"
|
8
10
|
autoload :Payment, "pay/payment"
|
9
11
|
autoload :Receipts, "pay/receipts"
|
10
12
|
|
@@ -66,6 +68,26 @@ module Pay
|
|
66
68
|
Pay::Billable.includers
|
67
69
|
end
|
68
70
|
|
71
|
+
def self.merchant_models
|
72
|
+
Pay::Merchant.includers
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.find_merchant(account_key, account_value)
|
76
|
+
merchant_models.each do |model|
|
77
|
+
case Pay::Adapter.current_adapter
|
78
|
+
when "postgresql"
|
79
|
+
return model.find_by("pay_data @> ?", {account_key.to_sym => account_value}.to_json)
|
80
|
+
when "mysql2"
|
81
|
+
return model.find_by("JSON_CONTAINS(pay_data, ?)", {account_key.to_sym => account_value}.to_json)
|
82
|
+
when "sqlite3"
|
83
|
+
return model.find_by("json_extract(pay_data, ?) =?", "$.#{account_key}", account_value)
|
84
|
+
else
|
85
|
+
model.find_by(pay_data: {account_key.to_sym => account_value})
|
86
|
+
end
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
69
91
|
def self.find_billable(processor:, processor_id:)
|
70
92
|
billable_models.each do |model|
|
71
93
|
if (record = model.find_by(processor: processor, processor_id: processor_id))
|
data/lib/pay/adapter.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Pay
|
2
|
+
module Adapter
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def self.current_adapter
|
6
|
+
if ActiveRecord::Base.respond_to?(:connection_db_config)
|
7
|
+
ActiveRecord::Base.connection_db_config.adapter
|
8
|
+
else
|
9
|
+
ActiveRecord::Base.connection_config[:adapter]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.json_column_type
|
14
|
+
case current_adapter
|
15
|
+
when "postgresql"
|
16
|
+
:jsonb
|
17
|
+
else
|
18
|
+
:json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/pay/billable.rb
CHANGED
@@ -26,6 +26,10 @@ module Pay
|
|
26
26
|
attribute :card_token, :string
|
27
27
|
attribute :pay_fake_processor_allowed, :boolean, default: false
|
28
28
|
|
29
|
+
# Account(s) for marketplace payments
|
30
|
+
store_accessor :pay_data, :stripe_account
|
31
|
+
store_accessor :pay_data, :braintree_account
|
32
|
+
|
29
33
|
validate :pay_fake_processor_is_allowed, if: :processor_changed?
|
30
34
|
end
|
31
35
|
|
@@ -151,9 +151,16 @@ module Pay
|
|
151
151
|
attrs = card_details_for_braintree_transaction(transaction)
|
152
152
|
attrs[:amount] = transaction.amount.to_f * 100
|
153
153
|
|
154
|
+
# Associate charge with subscription if we can
|
155
|
+
if transaction.subscription_id
|
156
|
+
attrs[:subscription] = Pay::Subscription.find_by(processor: :braintree, processor_id: transaction.subscription_id)
|
157
|
+
end
|
158
|
+
|
154
159
|
charge = billable.charges.find_or_initialize_by(
|
155
160
|
processor: :braintree,
|
156
|
-
processor_id: transaction.id
|
161
|
+
processor_id: transaction.id,
|
162
|
+
currency: transaction.currency_iso_code,
|
163
|
+
application_fee_amount: transaction.service_fee_amount
|
157
164
|
)
|
158
165
|
charge.update(attrs)
|
159
166
|
charge
|
@@ -23,6 +23,10 @@ module Pay
|
|
23
23
|
@pay_subscription = pay_subscription
|
24
24
|
end
|
25
25
|
|
26
|
+
def subscription(**options)
|
27
|
+
gateway.subscription.find(processor_id)
|
28
|
+
end
|
29
|
+
|
26
30
|
def cancel
|
27
31
|
subscription = processor_subscription
|
28
32
|
|
@@ -88,6 +92,8 @@ module Pay
|
|
88
92
|
end
|
89
93
|
|
90
94
|
def swap(plan)
|
95
|
+
raise ArgumentError, "plan must be a string" unless plan.is_a?(String)
|
96
|
+
|
91
97
|
if on_grace_period? && processor_plan == plan
|
92
98
|
resume
|
93
99
|
return
|
data/lib/pay/env.rb
CHANGED
@@ -17,6 +17,14 @@ module Pay
|
|
17
17
|
secrets&.dig(env, scope, name) ||
|
18
18
|
credentials&.dig(scope, name) ||
|
19
19
|
secrets&.dig(scope, name)
|
20
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage
|
21
|
+
Rails.logger.error <<~MESSAGE
|
22
|
+
Rails was unable to decrypt credentials. Pay checks the Rails credentials to look for API keys for payment processors.
|
23
|
+
|
24
|
+
Make sure to set the `RAILS_MASTER_KEY` env variable or in the .key file. To learn more, run "bin/rails credentials:help"
|
25
|
+
|
26
|
+
If you're not using Rails credentials, you can delete `config/credentials.yml.enc` and `config/credentials/`.
|
27
|
+
MESSAGE
|
20
28
|
end
|
21
29
|
|
22
30
|
def env
|
@@ -19,6 +19,10 @@ module Pay
|
|
19
19
|
@pay_subscription = pay_subscription
|
20
20
|
end
|
21
21
|
|
22
|
+
def subscription(**options)
|
23
|
+
pay_subscription
|
24
|
+
end
|
25
|
+
|
22
26
|
def cancel
|
23
27
|
pay_subscription.update(ends_at: Time.current.end_of_month)
|
24
28
|
end
|
@@ -48,6 +52,8 @@ module Pay
|
|
48
52
|
end
|
49
53
|
|
50
54
|
def swap(plan)
|
55
|
+
raise ArgumentError, "plan must be a string" unless plan.is_a?(String)
|
56
|
+
|
51
57
|
pay_subscription.update(processor_plan: plan)
|
52
58
|
end
|
53
59
|
end
|
data/lib/pay/merchant.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Pay
|
2
|
+
module Merchant
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
# Keep track of which Merchant models we have
|
6
|
+
class << self
|
7
|
+
attr_reader :includers
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.included(base = nil, &block)
|
11
|
+
@includers ||= []
|
12
|
+
@includers << base if base
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
included do
|
17
|
+
store_accessor :pay_data, :stripe_connect_account_id
|
18
|
+
store_accessor :pay_data, :onboarding_complete
|
19
|
+
end
|
20
|
+
|
21
|
+
def merchant
|
22
|
+
@merchant ||= merchant_processor_for(merchant_processor).new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def merchant_processor_for(name)
|
26
|
+
"Pay::#{name.to_s.classify}::Merchant".constantize
|
27
|
+
end
|
28
|
+
|
29
|
+
def stripe_connect_account_id?
|
30
|
+
!!stripe_connect_account_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def onboarding_complete?
|
34
|
+
!!onboarding_complete
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -24,6 +24,13 @@ module Pay
|
|
24
24
|
@pay_subscription = pay_subscription
|
25
25
|
end
|
26
26
|
|
27
|
+
def subscription(**options)
|
28
|
+
hash = PaddlePay::Subscription::User.list({subscription_id: processor_id}, options).try(:first)
|
29
|
+
OpenStruct.new(hash)
|
30
|
+
rescue ::PaddlePay::PaddlePayError => e
|
31
|
+
raise Pay::Paddle::Error, e
|
32
|
+
end
|
33
|
+
|
27
34
|
def cancel
|
28
35
|
subscription = processor_subscription
|
29
36
|
PaddlePay::Subscription::User.cancel(processor_id)
|
@@ -72,6 +79,8 @@ module Pay
|
|
72
79
|
end
|
73
80
|
|
74
81
|
def swap(plan)
|
82
|
+
raise ArgumentError, "plan must be a string" unless plan.is_a?(String)
|
83
|
+
|
75
84
|
attributes = {plan_id: plan, prorate: prorate}
|
76
85
|
attributes[:quantity] = quantity if quantity?
|
77
86
|
PaddlePay::Subscription::User.update(processor_id, attributes)
|
@@ -30,8 +30,10 @@ module Pay
|
|
30
30
|
params = {
|
31
31
|
amount: Integer(event["sale_gross"].to_f * 100),
|
32
32
|
card_type: event["payment_method"],
|
33
|
+
created_at: Time.zone.parse(event["event_time"]),
|
34
|
+
currency: event["currency"],
|
33
35
|
paddle_receipt_url: event["receipt_url"],
|
34
|
-
|
36
|
+
subscription: Pay::Subscription.find_by(processor: :paddle, processor_id: event["subscription_id"])
|
35
37
|
}
|
36
38
|
|
37
39
|
payment_information = Pay::Paddle::Billable.new(user).payment_information(event["subscription_id"])
|
data/lib/pay/stripe.rb
CHANGED
@@ -4,10 +4,14 @@ module Pay
|
|
4
4
|
autoload :Charge, "pay/stripe/charge"
|
5
5
|
autoload :Subscription, "pay/stripe/subscription"
|
6
6
|
autoload :Error, "pay/stripe/error"
|
7
|
+
autoload :Merchant, "pay/stripe/merchant"
|
7
8
|
|
8
9
|
module Webhooks
|
10
|
+
autoload :AccountUpdated, "pay/stripe/webhooks/account_updated"
|
9
11
|
autoload :ChargeRefunded, "pay/stripe/webhooks/charge_refunded"
|
10
12
|
autoload :ChargeSucceeded, "pay/stripe/webhooks/charge_succeeded"
|
13
|
+
autoload :CheckoutSessionCompleted, "pay/stripe/webhooks/checkout_session_completed"
|
14
|
+
autoload :CheckoutSessionAsyncPaymentSucceeded, "pay/stripe/webhooks/checkout_session_async_payment_succeeded"
|
11
15
|
autoload :CustomerDeleted, "pay/stripe/webhooks/customer_deleted"
|
12
16
|
autoload :CustomerUpdated, "pay/stripe/webhooks/customer_updated"
|
13
17
|
autoload :PaymentActionRequired, "pay/stripe/webhooks/payment_action_required"
|
@@ -81,6 +85,13 @@ module Pay
|
|
81
85
|
events.subscribe "stripe.payment_method.updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
82
86
|
events.subscribe "stripe.payment_method.card_automatically_updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
83
87
|
events.subscribe "stripe.payment_method.detached", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
88
|
+
|
89
|
+
# If an account is updated in stripe, we should update it as well
|
90
|
+
events.subscribe "stripe.account.updated", Pay::Stripe::Webhooks::AccountUpdated.new
|
91
|
+
|
92
|
+
# Handle subscriptions in Stripe Checkout Sessions
|
93
|
+
events.subscribe "stripe.checkout.session.completed", Pay::Stripe::Webhooks::CheckoutSessionCompleted.new
|
94
|
+
events.subscribe "stripe.checkout.session.async_payment_succeeded", Pay::Stripe::Webhooks::CheckoutSessionAsyncPaymentSucceeded.new
|
84
95
|
end
|
85
96
|
end
|
86
97
|
end
|
data/lib/pay/stripe/billable.rb
CHANGED
@@ -10,6 +10,7 @@ module Pay
|
|
10
10
|
:email,
|
11
11
|
:customer_name,
|
12
12
|
:card_token,
|
13
|
+
:stripe_account,
|
13
14
|
to: :billable
|
14
15
|
|
15
16
|
class << self
|
@@ -27,17 +28,17 @@ module Pay
|
|
27
28
|
# Returns Stripe::Customer
|
28
29
|
def customer
|
29
30
|
stripe_customer = if processor_id?
|
30
|
-
::Stripe::Customer.retrieve(processor_id)
|
31
|
+
::Stripe::Customer.retrieve(processor_id, stripe_options)
|
31
32
|
else
|
32
|
-
sc = ::Stripe::Customer.create(email: email, name: customer_name)
|
33
|
-
billable.update(processor: :stripe, processor_id: sc.id)
|
33
|
+
sc = ::Stripe::Customer.create({email: email, name: customer_name}, stripe_options)
|
34
|
+
billable.update(processor: :stripe, processor_id: sc.id, stripe_account: stripe_account)
|
34
35
|
sc
|
35
36
|
end
|
36
37
|
|
37
38
|
# Update the user's card on file if a token was passed in
|
38
39
|
if card_token.present?
|
39
|
-
payment_method = ::Stripe::PaymentMethod.attach(card_token, customer: stripe_customer.id)
|
40
|
-
stripe_customer = ::Stripe::Customer.update(stripe_customer.id, invoice_settings: {default_payment_method: payment_method.id})
|
40
|
+
payment_method = ::Stripe::PaymentMethod.attach(card_token, {customer: stripe_customer.id}, stripe_options)
|
41
|
+
stripe_customer = ::Stripe::Customer.update(stripe_customer.id, {invoice_settings: {default_payment_method: payment_method.id}}, stripe_options)
|
41
42
|
update_card_on_file(payment_method.card)
|
42
43
|
end
|
43
44
|
|
@@ -60,11 +61,12 @@ module Pay
|
|
60
61
|
payment_method: stripe_customer.invoice_settings.default_payment_method
|
61
62
|
}.merge(options)
|
62
63
|
|
63
|
-
payment_intent = ::Stripe::PaymentIntent.create(args)
|
64
|
+
payment_intent = ::Stripe::PaymentIntent.create(args, stripe_options)
|
64
65
|
Pay::Payment.new(payment_intent).validate
|
65
66
|
|
66
67
|
# Create a new charge object
|
67
|
-
|
68
|
+
charge = payment_intent.charges.first
|
69
|
+
Pay::Stripe::Charge.sync(charge.id, object: charge)
|
68
70
|
rescue ::Stripe::StripeError => e
|
69
71
|
raise Pay::Stripe::Error, e
|
70
72
|
end
|
@@ -86,16 +88,15 @@ module Pay
|
|
86
88
|
# Load the Stripe customer to verify it exists and update card if needed
|
87
89
|
opts[:customer] = customer.id
|
88
90
|
|
89
|
-
|
90
|
-
|
91
|
+
# Create subscription on Stripe
|
92
|
+
stripe_sub = ::Stripe::Subscription.create(opts, stripe_options)
|
93
|
+
|
94
|
+
# Save Pay::Subscription
|
95
|
+
subscription = Pay::Stripe::Subscription.sync(stripe_sub.id, object: stripe_sub, name: name)
|
91
96
|
|
92
97
|
# No trial, card requires SCA
|
93
98
|
if subscription.incomplete?
|
94
99
|
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
100
|
end
|
100
101
|
|
101
102
|
subscription
|
@@ -111,8 +112,8 @@ module Pay
|
|
111
112
|
|
112
113
|
return true if payment_method_id == stripe_customer.invoice_settings.default_payment_method
|
113
114
|
|
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})
|
115
|
+
payment_method = ::Stripe::PaymentMethod.attach(payment_method_id, {customer: stripe_customer.id}, stripe_options)
|
116
|
+
::Stripe::Customer.update(stripe_customer.id, {invoice_settings: {default_payment_method: payment_method.id}}, stripe_options)
|
116
117
|
|
117
118
|
update_card_on_file(payment_method.card)
|
118
119
|
true
|
@@ -121,33 +122,33 @@ module Pay
|
|
121
122
|
end
|
122
123
|
|
123
124
|
def update_email!
|
124
|
-
::Stripe::Customer.update(processor_id, {email: email, name: customer_name})
|
125
|
+
::Stripe::Customer.update(processor_id, {email: email, name: customer_name}, stripe_options)
|
125
126
|
end
|
126
127
|
|
127
128
|
def processor_subscription(subscription_id, options = {})
|
128
|
-
::Stripe::Subscription.retrieve(options.merge(id: subscription_id))
|
129
|
+
::Stripe::Subscription.retrieve(options.merge(id: subscription_id), stripe_options)
|
129
130
|
end
|
130
131
|
|
131
132
|
def invoice!(options = {})
|
132
133
|
return unless processor_id?
|
133
|
-
::Stripe::Invoice.create(options.merge(customer: processor_id)).pay
|
134
|
+
::Stripe::Invoice.create(options.merge(customer: processor_id), stripe_options).pay
|
134
135
|
end
|
135
136
|
|
136
137
|
def upcoming_invoice
|
137
|
-
::Stripe::Invoice.upcoming(customer: processor_id)
|
138
|
+
::Stripe::Invoice.upcoming({customer: processor_id}, stripe_options)
|
138
139
|
end
|
139
140
|
|
140
141
|
# Used by webhooks when the customer or source changes
|
141
142
|
def sync_card_from_stripe
|
142
143
|
if (payment_method_id = customer.invoice_settings.default_payment_method)
|
143
|
-
update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id).card
|
144
|
+
update_card_on_file ::Stripe::PaymentMethod.retrieve(payment_method_id, stripe_options).card
|
144
145
|
else
|
145
146
|
billable.update(card_type: nil, card_last4: nil)
|
146
147
|
end
|
147
148
|
end
|
148
149
|
|
149
150
|
def create_setup_intent
|
150
|
-
::Stripe::SetupIntent.create(customer: processor_id, usage: :off_session)
|
151
|
+
::Stripe::SetupIntent.create({customer: processor_id, usage: :off_session}, stripe_options)
|
151
152
|
end
|
152
153
|
|
153
154
|
def trial_end_date(stripe_sub)
|
@@ -167,19 +168,14 @@ module Pay
|
|
167
168
|
billable.card_token = nil
|
168
169
|
end
|
169
170
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
card_exp_year: object.payment_method_details.card.exp_year,
|
179
|
-
created_at: Time.zone.at(object.created)
|
180
|
-
)
|
181
|
-
|
182
|
-
charge
|
171
|
+
# Syncs a customer's subscriptions from Stripe to the database
|
172
|
+
def sync_subscriptions
|
173
|
+
subscriptions = ::Stripe::Subscription.list({customer: customer}, stripe_options)
|
174
|
+
subscriptions.map do |subscription|
|
175
|
+
Pay::Stripe::Subscription.sync(subscription.id)
|
176
|
+
end
|
177
|
+
rescue ::Stripe::StripeError => e
|
178
|
+
raise Pay::Stripe::Error, e
|
183
179
|
end
|
184
180
|
|
185
181
|
# https://stripe.com/docs/api/checkout/sessions/create
|
@@ -213,7 +209,7 @@ module Pay
|
|
213
209
|
}
|
214
210
|
end
|
215
211
|
|
216
|
-
::Stripe::Checkout::Session.create(args.merge(options))
|
212
|
+
::Stripe::Checkout::Session.create(args.merge(options), stripe_options)
|
217
213
|
end
|
218
214
|
|
219
215
|
# https://stripe.com/docs/api/checkout/sessions/create
|
@@ -240,7 +236,14 @@ module Pay
|
|
240
236
|
customer: processor_id,
|
241
237
|
return_url: options.delete(:return_url) || root_url
|
242
238
|
}
|
243
|
-
::Stripe::BillingPortal::Session.create(args.merge(options))
|
239
|
+
::Stripe::BillingPortal::Session.create(args.merge(options), stripe_options)
|
240
|
+
end
|
241
|
+
|
242
|
+
private
|
243
|
+
|
244
|
+
# Options for Stripe requests
|
245
|
+
def stripe_options
|
246
|
+
{stripe_account: stripe_account}.compact
|
244
247
|
end
|
245
248
|
end
|
246
249
|
end
|