pay 2.6.11 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c258d50a32d486777f2439f2fd2cd75e6cac1adba558afe630b9eda760c87717
4
- data.tar.gz: 1f079e5382a0f8c3cda2e7b70b56c36162bc32926dae8b9c5226ed1c2e508160
3
+ metadata.gz: d696d24ee2bb2b4827f6d6e31db738752ebb2eadca4ea0e79144518fc9375be9
4
+ data.tar.gz: 8aad550b117bee7e28c9231832f4f344c37054db4f1a7d0176f034c780d0abed
5
5
  SHA512:
6
- metadata.gz: ad9e9b98b5ed50f2e0f6599742b70f3c274afdc994949b445d921a5ae4451fbbaf2afcbad47e8d7d2a2c1b382fbb3ab3f97a85b2640048b937fab4d8dca10920
7
- data.tar.gz: 21eaa1e667271af7f64e3e1f4544c8f1f6e11e32d3dec80e9e70b05159ac0a4ae9dba390b1e4f1a6cac6b8223df547ec8bc87bb7505425a365fe7a06b713c3ea
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
@@ -0,0 +1,5 @@
1
+ module Pay
2
+ def self.table_name_prefix
3
+ "pay_"
4
+ end
5
+ end
@@ -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
 
@@ -5,18 +5,11 @@ class AddDataToPayModels < ActiveRecord::Migration[4.2]
5
5
  end
6
6
 
7
7
  def data_column_type
8
- default_hash = ActiveRecord::Base.configurations.default_hash
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
- :text
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
@@ -1,4 +1,4 @@
1
- class AddCurrencyToPayCharges < ActiveRecord::Migration[6.1]
1
+ class AddCurrencyToPayCharges < ActiveRecord::Migration[4.2]
2
2
  def change
3
3
  add_column :pay_charges, :currency, :string
4
4
  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))
@@ -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
 
@@ -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
@@ -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
@@ -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
- created_at: Time.zone.parse(event["event_time"])
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,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
@@ -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_account: stripe_account})
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_account: stripe_account})
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_account: stripe_account})
41
+ stripe_customer = ::Stripe::Customer.update(stripe_customer.id, {invoice_settings: {default_payment_method: payment_method.id}}, {stripe_account: stripe_account})
41
42
  update_card_on_file(payment_method.card)
42
43
  end
43
44
 
@@ -60,7 +61,7 @@ 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_account: stripe_account})
64
65
  Pay::Payment.new(payment_intent).validate
65
66
 
66
67
  # Create a new charge object
@@ -86,8 +87,8 @@ module Pay
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
- charge.update(
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
 
@@ -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
@@ -240,7 +251,7 @@ module Pay
240
251
  customer: processor_id,
241
252
  return_url: options.delete(:return_url) || root_url
242
253
  }
243
- ::Stripe::BillingPortal::Session.create(args.merge(options))
254
+ ::Stripe::BillingPortal::Session.create(args.merge(options), {stripe_account: stripe_account})
244
255
  end
245
256
  end
246
257
  end
@@ -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(id: processor_id, expand: ["customer", "invoice.subscription"])
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
- def refund!(amount_to_refund)
19
- ::Stripe::Refund.create(charge: processor_id, amount: amount_to_refund)
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
 
@@ -28,19 +29,15 @@ module Pay
28
29
  end
29
30
 
30
31
  def cancel
31
- subscription = processor_subscription
32
- subscription.cancel_at_period_end = true
33
- subscription.save
34
-
35
- new_ends_at = on_trial? ? trial_ends_at : Time.at(subscription.current_period_end)
36
- pay_subscription.update(ends_at: new_ends_at)
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)))
37
34
  rescue ::Stripe::StripeError => e
38
35
  raise Pay::Stripe::Error, e
39
36
  end
40
37
 
41
38
  def cancel_now!
42
- processor_subscription.delete
43
- pay_subscription.update(ends_at: Time.zone.now, status: :canceled)
39
+ ::Stripe::Subscription.delete(processor_id, {stripe_account: stripe_account})
40
+ pay_subscription.update(ends_at: Time.current, status: :canceled)
44
41
  rescue ::Stripe::StripeError => e
45
42
  raise Pay::Stripe::Error, e
46
43
  end
@@ -68,23 +65,31 @@ module Pay
68
65
  raise StandardError, "You can only resume subscriptions within their grace period."
69
66
  end
70
67
 
71
- subscription = processor_subscription
72
- subscription.plan = processor_plan
73
- subscription.trial_end = on_trial? ? trial_ends_at.to_i : "now"
74
- subscription.cancel_at_period_end = false
75
- subscription.save
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
+ )
76
77
  rescue ::Stripe::StripeError => e
77
78
  raise Pay::Stripe::Error, e
78
79
  end
79
80
 
80
81
  def swap(plan)
81
- subscription = processor_subscription
82
- subscription.cancel_at_period_end = false
83
- subscription.plan = plan
84
- subscription.proration_behavior = (prorate ? "create_prorations" : "none")
85
- subscription.trial_end = on_trial? ? trial_ends_at.to_i : "now"
86
- subscription.quantity = quantity if quantity?
87
- subscription.save
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
+ )
88
93
  rescue ::Stripe::StripeError => e
89
94
  raise Pay::Stripe::Error, e
90
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.status = object.status
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
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "2.6.11"
2
+ VERSION = "2.7.0"
3
3
  end
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.6.11
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-05-04 00:00:00.000000000 Z
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,7 +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
144
- - db/migrate/20210423235138_add_currency_to_pay_charges.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
145
148
  - lib/generators/active_record/pay_generator.rb
146
149
  - lib/generators/active_record/templates/migration.rb
147
150
  - lib/generators/pay/email_views_generator.rb
@@ -149,6 +152,7 @@ files:
149
152
  - lib/generators/pay/pay_generator.rb
150
153
  - lib/generators/pay/views_generator.rb
151
154
  - lib/pay.rb
155
+ - lib/pay/adapter.rb
152
156
  - lib/pay/billable.rb
153
157
  - lib/pay/billable/sync_email.rb
154
158
  - lib/pay/braintree.rb
@@ -172,6 +176,7 @@ files:
172
176
  - lib/pay/fake_processor/charge.rb
173
177
  - lib/pay/fake_processor/error.rb
174
178
  - lib/pay/fake_processor/subscription.rb
179
+ - lib/pay/merchant.rb
175
180
  - lib/pay/paddle.rb
176
181
  - lib/pay/paddle/billable.rb
177
182
  - lib/pay/paddle/charge.rb
@@ -189,7 +194,9 @@ files:
189
194
  - lib/pay/stripe/billable.rb
190
195
  - lib/pay/stripe/charge.rb
191
196
  - lib/pay/stripe/error.rb
197
+ - lib/pay/stripe/merchant.rb
192
198
  - lib/pay/stripe/subscription.rb
199
+ - lib/pay/stripe/webhooks/account_updated.rb
193
200
  - lib/pay/stripe/webhooks/charge_refunded.rb
194
201
  - lib/pay/stripe/webhooks/charge_succeeded.rb
195
202
  - lib/pay/stripe/webhooks/customer_deleted.rb
@@ -223,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
230
  - !ruby/object:Gem::Version
224
231
  version: '0'
225
232
  requirements: []
226
- rubygems_version: 3.2.3
233
+ rubygems_version: 3.2.15
227
234
  signing_key:
228
235
  specification_version: 4
229
236
  summary: Payments engine for Ruby on Rails