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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d696d24ee2bb2b4827f6d6e31db738752ebb2eadca4ea0e79144518fc9375be9
|
4
|
+
data.tar.gz: 8aad550b117bee7e28c9231832f4f344c37054db4f1a7d0176f034c780d0abed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5dc610b8d7b67ed4073fea783b290d3cd6ada3f4df1ed7bac26a0c4770f4a5ab854bf492fe6541f14b069ae61b10369024689a9f832d625ba2201a14deb24fc1
|
7
|
+
data.tar.gz: 3801e3d1da5a833869ed46d28e04d633df5e1b55e51900bcae1a8b437663b93ee1b5ab45698cb54e00a145fb1752cb4c195ec877070b367b79d8c3b03ce81e8d
|
data/README.md
CHANGED
@@ -64,6 +64,9 @@ To add the migrations to your application, run the following migration:
|
|
64
64
|
|
65
65
|
`bin/rails pay:install:migrations`
|
66
66
|
|
67
|
+
>If your models rely on non integer ids (uuids for example) you will need to alter the `create_pay_subscriptions` and `create_pay_charges` migrations to ensure the `owner_id` column's type matches the model's id's format.
|
68
|
+
> As commented in the migrations adding a type parameter to the `t.references :owner` line will ensure the `owner_id` column is of the correct type.
|
69
|
+
|
67
70
|
We also need to run migrations to add Pay to the User, Account, Team, etc models that we want to make payments in our app.
|
68
71
|
|
69
72
|
`bin/rails g pay User`
|
data/app/models/pay.rb
ADDED
data/app/models/pay/charge.rb
CHANGED
@@ -7,6 +7,7 @@ module Pay
|
|
7
7
|
|
8
8
|
# Associations
|
9
9
|
belongs_to :owner, polymorphic: true
|
10
|
+
belongs_to :subscription, optional: true, class_name: "Pay::Subscription", foreign_key: :pay_subscription_id
|
10
11
|
|
11
12
|
# Scopes
|
12
13
|
scope :sorted, -> { order(created_at: :desc) }
|
@@ -19,6 +20,7 @@ module Pay
|
|
19
20
|
validates :card_type, presence: true
|
20
21
|
|
21
22
|
store_accessor :data, :paddle_receipt_url
|
23
|
+
store_accessor :data, :stripe_account
|
22
24
|
|
23
25
|
# Helpers for payment processors
|
24
26
|
%w[braintree stripe paddle fake_processor].each do |processor_name|
|
@@ -9,6 +9,7 @@ module Pay
|
|
9
9
|
|
10
10
|
# Associations
|
11
11
|
belongs_to :owner, polymorphic: true
|
12
|
+
has_many :charges, class_name: "Pay::Charge", foreign_key: :pay_subscription_id
|
12
13
|
|
13
14
|
# Validations
|
14
15
|
validates :name, presence: true
|
@@ -31,6 +32,7 @@ module Pay
|
|
31
32
|
store_accessor :data, :paddle_update_url
|
32
33
|
store_accessor :data, :paddle_cancel_url
|
33
34
|
store_accessor :data, :paddle_paused_from
|
35
|
+
store_accessor :data, :stripe_account
|
34
36
|
|
35
37
|
attribute :prorate, :boolean, default: true
|
36
38
|
|
@@ -94,6 +96,11 @@ module Pay
|
|
94
96
|
past_due? || incomplete?
|
95
97
|
end
|
96
98
|
|
99
|
+
def change_quantity(quantity)
|
100
|
+
payment_processor.change_quantity(quantity)
|
101
|
+
update(quantity: quantity)
|
102
|
+
end
|
103
|
+
|
97
104
|
def resume
|
98
105
|
payment_processor.resume
|
99
106
|
update(ends_at: nil, status: "active")
|
@@ -110,8 +117,8 @@ module Pay
|
|
110
117
|
owner.invoice!(subscription_id: processor_id)
|
111
118
|
end
|
112
119
|
|
113
|
-
def processor_subscription(options
|
114
|
-
|
120
|
+
def processor_subscription(**options)
|
121
|
+
payment_processor.subscription(**options)
|
115
122
|
end
|
116
123
|
|
117
124
|
def latest_payment
|
@@ -13,7 +13,7 @@
|
|
13
13
|
sessionId: '<%= session.id %>'
|
14
14
|
}).then(function (result) {
|
15
15
|
if (result.error) {
|
16
|
-
document.getElementById(
|
16
|
+
document.getElementById("error-for-#{session.id}").innerText = result.error.message;
|
17
17
|
}
|
18
18
|
});
|
19
19
|
});
|
@@ -5,18 +5,11 @@ class AddDataToPayModels < ActiveRecord::Migration[4.2]
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def data_column_type
|
8
|
-
|
9
|
-
|
10
|
-
# Rails 6.1 uses a symbol key instead of a string
|
11
|
-
adapter = default_hash.dig(:adapter) || default_hash.dig("adapter")
|
12
|
-
|
13
|
-
case adapter
|
14
|
-
when "mysql2"
|
15
|
-
:json
|
8
|
+
case Pay::Adapter.current_adapter
|
16
9
|
when "postgresql"
|
17
10
|
:jsonb
|
18
11
|
else
|
19
|
-
:
|
12
|
+
:json
|
20
13
|
end
|
21
14
|
end
|
22
15
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class AddDataToPayBillable < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
# Load all the billable models
|
4
|
+
Rails.application.eager_load!
|
5
|
+
|
6
|
+
Pay.billable_models.each do |model|
|
7
|
+
add_column model.table_name, :pay_data, data_column_type
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def data_column_type
|
12
|
+
case Pay::Adapter.current_adapter
|
13
|
+
when "postgresql"
|
14
|
+
:jsonb
|
15
|
+
else
|
16
|
+
:json
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class AddApplicationFeeToPayModels < ActiveRecord::Migration[4.2]
|
2
|
+
def change
|
3
|
+
add_column :pay_charges, :application_fee_amount, :integer
|
4
|
+
add_column :pay_subscriptions, :application_fee_percent, :decimal, precision: 8, scale: 2
|
5
|
+
add_column :pay_charges, :pay_subscription_id, :integer
|
6
|
+
end
|
7
|
+
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,13 @@
|
|
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
|
+
end
|
13
|
+
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
|
|
@@ -19,7 +19,9 @@ module Pay
|
|
19
19
|
# Returns Braintree::Customer
|
20
20
|
def customer
|
21
21
|
if processor_id?
|
22
|
-
gateway.customer.find(processor_id)
|
22
|
+
customer = gateway.customer.find(processor_id)
|
23
|
+
update_card card_token if card_token.present?
|
24
|
+
customer
|
23
25
|
else
|
24
26
|
result = gateway.customer.create(
|
25
27
|
email: email,
|
@@ -149,9 +151,16 @@ module Pay
|
|
149
151
|
attrs = card_details_for_braintree_transaction(transaction)
|
150
152
|
attrs[:amount] = transaction.amount.to_f * 100
|
151
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
|
+
|
152
159
|
charge = billable.charges.find_or_initialize_by(
|
153
160
|
processor: :braintree,
|
154
|
-
processor_id: transaction.id
|
161
|
+
processor_id: transaction.id,
|
162
|
+
currency: transaction.currency_iso_code,
|
163
|
+
application_fee_amount: transaction.service_fee_amount
|
155
164
|
)
|
156
165
|
charge.update(attrs)
|
157
166
|
charge
|
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
|
data/lib/pay/paddle.rb
CHANGED
@@ -44,6 +44,13 @@ module Pay
|
|
44
44
|
options.merge(owner_sgid: owner.to_sgid.to_s).to_json
|
45
45
|
end
|
46
46
|
|
47
|
+
def self.owner_from_passthrough(passthrough)
|
48
|
+
passthrough_json = JSON.parse(passthrough)
|
49
|
+
GlobalID::Locator.locate_signed(passthrough_json["owner_sgid"])
|
50
|
+
rescue JSON::ParserError
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
47
54
|
def self.configure_webhooks
|
48
55
|
Pay::Webhooks.configure do |events|
|
49
56
|
events.subscribe "paddle.subscription_created", Pay::Paddle::Webhooks::SubscriptionCreated.new
|
@@ -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)
|
@@ -13,7 +13,7 @@ module Pay
|
|
13
13
|
owner = Pay.find_billable(processor: :paddle, processor_id: event["user_id"])
|
14
14
|
|
15
15
|
if owner.nil?
|
16
|
-
owner =
|
16
|
+
owner = Pay::Paddle.owner_from_passthrough(event["passthrough"])
|
17
17
|
owner&.update!(processor: "paddle", processor_id: event["user_id"])
|
18
18
|
end
|
19
19
|
|
@@ -44,15 +44,6 @@ module Pay
|
|
44
44
|
|
45
45
|
subscription.save!
|
46
46
|
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
def owner_by_passtrough(passthrough, product_id)
|
51
|
-
passthrough_json = JSON.parse(passthrough)
|
52
|
-
GlobalID::Locator.locate_signed(passthrough_json["owner_sgid"])
|
53
|
-
rescue JSON::ParserError
|
54
|
-
nil
|
55
|
-
end
|
56
47
|
end
|
57
48
|
end
|
58
49
|
end
|
@@ -4,7 +4,17 @@ module Pay
|
|
4
4
|
class SubscriptionPaymentSucceeded
|
5
5
|
def call(event)
|
6
6
|
billable = Pay.find_billable(processor: :paddle, processor_id: event["user_id"])
|
7
|
-
|
7
|
+
|
8
|
+
if billable.nil?
|
9
|
+
billable = Pay::Paddle.owner_from_passthrough(event["passthrough"])
|
10
|
+
billable&.update!(processor: "paddle", processor_id: event["user_id"])
|
11
|
+
end
|
12
|
+
|
13
|
+
if billable.nil?
|
14
|
+
Rails.logger.error("[Pay] Unable to find Pay::Billable with owner: '#{event["passthrough"]}'. Searched these models: #{Pay.billable_models.join(", ")}")
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
8
18
|
return if billable.charges.where(processor_id: event["subscription_payment_id"]).any?
|
9
19
|
|
10
20
|
charge = create_charge(billable, event)
|
@@ -20,8 +30,10 @@ module Pay
|
|
20
30
|
params = {
|
21
31
|
amount: Integer(event["sale_gross"].to_f * 100),
|
22
32
|
card_type: event["payment_method"],
|
33
|
+
created_at: Time.zone.parse(event["event_time"]),
|
34
|
+
currency: event["currency"],
|
23
35
|
paddle_receipt_url: event["receipt_url"],
|
24
|
-
|
36
|
+
subscription: Pay::Subscription.find_by(processor: :paddle, processor_id: event["subscription_id"])
|
25
37
|
}
|
26
38
|
|
27
39
|
payment_information = Pay::Paddle::Billable.new(user).payment_information(event["subscription_id"])
|
data/lib/pay/stripe.rb
CHANGED
@@ -4,8 +4,10 @@ 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"
|
11
13
|
autoload :CustomerDeleted, "pay/stripe/webhooks/customer_deleted"
|
@@ -81,6 +83,9 @@ module Pay
|
|
81
83
|
events.subscribe "stripe.payment_method.updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
82
84
|
events.subscribe "stripe.payment_method.card_automatically_updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
83
85
|
events.subscribe "stripe.payment_method.detached", Pay::Stripe::Webhooks::PaymentMethodUpdated.new
|
86
|
+
|
87
|
+
# If an account is updated in stripe, we should update it as well
|
88
|
+
events.subscribe "stripe.account.updated", Pay::Stripe::Webhooks::AccountUpdated.new
|
84
89
|
end
|
85
90
|
end
|
86
91
|
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
|
@@ -26,23 +27,22 @@ module Pay
|
|
26
27
|
#
|
27
28
|
# Returns Stripe::Customer
|
28
29
|
def customer
|
29
|
-
if processor_id?
|
30
|
-
::Stripe::Customer.retrieve(processor_id)
|
30
|
+
stripe_customer = if processor_id?
|
31
|
+
::Stripe::Customer.retrieve(processor_id, {stripe_account: stripe_account})
|
31
32
|
else
|
32
|
-
|
33
|
-
billable.update(processor: :stripe, processor_id:
|
34
|
-
|
35
|
-
|
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
|
33
|
+
sc = ::Stripe::Customer.create({email: email, name: customer_name}, {stripe_account: stripe_account})
|
34
|
+
billable.update(processor: :stripe, processor_id: sc.id, stripe_account: stripe_account)
|
35
|
+
sc
|
36
|
+
end
|
43
37
|
|
44
|
-
|
38
|
+
# Update the user's card on file if a token was passed in
|
39
|
+
if card_token.present?
|
40
|
+
payment_method = ::Stripe::PaymentMethod.attach(card_token, {customer: stripe_customer.id}, {stripe_account: stripe_account})
|
41
|
+
stripe_customer = ::Stripe::Customer.update(stripe_customer.id, {invoice_settings: {default_payment_method: payment_method.id}}, {stripe_account: stripe_account})
|
42
|
+
update_card_on_file(payment_method.card)
|
45
43
|
end
|
44
|
+
|
45
|
+
stripe_customer
|
46
46
|
rescue ::Stripe::StripeError => e
|
47
47
|
raise Pay::Stripe::Error, e
|
48
48
|
end
|
@@ -61,7 +61,7 @@ module Pay
|
|
61
61
|
payment_method: stripe_customer.invoice_settings.default_payment_method
|
62
62
|
}.merge(options)
|
63
63
|
|
64
|
-
payment_intent = ::Stripe::PaymentIntent.create(args)
|
64
|
+
payment_intent = ::Stripe::PaymentIntent.create(args, {stripe_account: stripe_account})
|
65
65
|
Pay::Payment.new(payment_intent).validate
|
66
66
|
|
67
67
|
# Create a new charge object
|
@@ -84,10 +84,11 @@ module Pay
|
|
84
84
|
# Inherit trial from plan unless trial override was specified
|
85
85
|
opts[:trial_from_plan] = true unless opts[:trial_period_days]
|
86
86
|
|
87
|
+
# Load the Stripe customer to verify it exists and update card if needed
|
87
88
|
opts[:customer] = customer.id
|
88
89
|
|
89
|
-
stripe_sub = ::Stripe::Subscription.create(opts)
|
90
|
-
subscription = billable.create_pay_subscription(stripe_sub, "stripe", name, plan, status: stripe_sub.status, quantity: quantity)
|
90
|
+
stripe_sub = ::Stripe::Subscription.create(opts, {stripe_account: stripe_account})
|
91
|
+
subscription = billable.create_pay_subscription(stripe_sub, "stripe", name, plan, status: stripe_sub.status, quantity: quantity, stripe_account: stripe_account, application_fee_percent: stripe_sub.application_fee_percent)
|
91
92
|
|
92
93
|
# No trial, card requires SCA
|
93
94
|
if subscription.incomplete?
|
@@ -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_account: stripe_account})
|
116
|
+
::Stripe::Customer.update(stripe_customer.id, {invoice_settings: {default_payment_method: payment_method.id}}, {stripe_account: stripe_account})
|
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_account: stripe_account})
|
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_account: stripe_account})
|
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_account: stripe_account}).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_account: stripe_account})
|
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_account: stripe_account}).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_account: stripe_account})
|
151
152
|
end
|
152
153
|
|
153
154
|
def trial_end_date(stripe_sub)
|
@@ -170,15 +171,25 @@ module Pay
|
|
170
171
|
def save_pay_charge(object)
|
171
172
|
charge = billable.charges.find_or_initialize_by(processor: :stripe, processor_id: object.id)
|
172
173
|
|
173
|
-
|
174
|
+
attrs = {
|
174
175
|
amount: object.amount,
|
175
176
|
card_last4: object.payment_method_details.card.last4,
|
176
177
|
card_type: object.payment_method_details.card.brand,
|
177
178
|
card_exp_month: object.payment_method_details.card.exp_month,
|
178
179
|
card_exp_year: object.payment_method_details.card.exp_year,
|
179
|
-
created_at: Time.zone.at(object.created)
|
180
|
-
|
180
|
+
created_at: Time.zone.at(object.created),
|
181
|
+
currency: object.currency,
|
182
|
+
stripe_account: stripe_account,
|
183
|
+
application_fee_amount: object.application_fee_amount
|
184
|
+
}
|
185
|
+
|
186
|
+
# Associate charge with subscription if we can
|
187
|
+
if object.invoice
|
188
|
+
invoice = (object.invoice.is_a?(::Stripe::Invoice) ? object.invoice : ::Stripe::Invoice.retrieve(object.invoice))
|
189
|
+
attrs[:subscription] = Pay::Subscription.find_by(processor: :stripe, processor_id: invoice.subscription)
|
190
|
+
end
|
181
191
|
|
192
|
+
charge.update(attrs)
|
182
193
|
charge
|
183
194
|
end
|
184
195
|
|
@@ -198,8 +209,8 @@ module Pay
|
|
198
209
|
payment_method_types: ["card"],
|
199
210
|
mode: "payment",
|
200
211
|
# These placeholder URLs will be replaced in a following step.
|
201
|
-
success_url: root_url,
|
202
|
-
cancel_url: root_url
|
212
|
+
success_url: options.delete(:success_url) || root_url,
|
213
|
+
cancel_url: options.delete(:cancel_url) || root_url
|
203
214
|
}
|
204
215
|
|
205
216
|
# Line items are optional
|
@@ -213,7 +224,7 @@ module Pay
|
|
213
224
|
}
|
214
225
|
end
|
215
226
|
|
216
|
-
::Stripe::Checkout::Session.create(args.merge(options))
|
227
|
+
::Stripe::Checkout::Session.create(args.merge(options), {stripe_account: stripe_account})
|
217
228
|
end
|
218
229
|
|
219
230
|
# https://stripe.com/docs/api/checkout/sessions/create
|
@@ -221,10 +232,11 @@ module Pay
|
|
221
232
|
# checkout_charge(amount: 15_00, name: "T-shirt", quantity: 2)
|
222
233
|
#
|
223
234
|
def checkout_charge(amount:, name:, quantity: 1, **options)
|
235
|
+
currency = options.delete(:currency) || "usd"
|
224
236
|
checkout(
|
225
237
|
line_items: {
|
226
238
|
price_data: {
|
227
|
-
currency:
|
239
|
+
currency: currency,
|
228
240
|
product_data: {name: name},
|
229
241
|
unit_amount: amount
|
230
242
|
},
|
@@ -237,9 +249,9 @@ module Pay
|
|
237
249
|
def billing_portal(**options)
|
238
250
|
args = {
|
239
251
|
customer: processor_id,
|
240
|
-
return_url: options
|
252
|
+
return_url: options.delete(:return_url) || root_url
|
241
253
|
}
|
242
|
-
::Stripe::BillingPortal::Session.create(args.merge(options))
|
254
|
+
::Stripe::BillingPortal::Session.create(args.merge(options), {stripe_account: stripe_account})
|
243
255
|
end
|
244
256
|
end
|
245
257
|
end
|