pay 2.6.6 → 2.6.11

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: aab238996fb28cf924267575d0af02c0efce2a41a44571aced25144547c92cac
4
- data.tar.gz: 3f038c66725ccee4d08be97baebed65ec51b9dbf5ae731970a4319334a7093b0
3
+ metadata.gz: c258d50a32d486777f2439f2fd2cd75e6cac1adba558afe630b9eda760c87717
4
+ data.tar.gz: 1f079e5382a0f8c3cda2e7b70b56c36162bc32926dae8b9c5226ed1c2e508160
5
5
  SHA512:
6
- metadata.gz: 84d80003f9e6102750529c35618d1b7602c8361015dc61a32f361c22ae62f02384d60e2fc59ec04df8264e8a27e90bcd0a8381516db61a17b3bf3dcf39d7c4f7
7
- data.tar.gz: 283b1e89926cd377b8204d96ca01cb4646e2cead0342ea212292731d7f22864799e1f7ed0c311afc4f5ba93781092820d36578c8a52767c0ad134b943f390b26
6
+ metadata.gz: ad9e9b98b5ed50f2e0f6599742b70f3c274afdc994949b445d921a5ae4451fbbaf2afcbad47e8d7d2a2c1b382fbb3ab3f97a85b2640048b937fab4d8dca10920
7
+ data.tar.gz: 21eaa1e667271af7f64e3e1f4544c8f1f6e11e32d3dec80e9e70b05159ac0a4ae9dba390b1e4f1a6cac6b8223df547ec8bc87bb7505425a365fe7a06b713c3ea
@@ -94,6 +94,11 @@ module Pay
94
94
  past_due? || incomplete?
95
95
  end
96
96
 
97
+ def change_quantity(quantity)
98
+ payment_processor.change_quantity(quantity)
99
+ update(quantity: quantity)
100
+ end
101
+
97
102
  def resume
98
103
  payment_processor.resume
99
104
  update(ends_at: nil, status: "active")
@@ -110,8 +115,8 @@ module Pay
110
115
  owner.invoice!(subscription_id: processor_id)
111
116
  end
112
117
 
113
- def processor_subscription(options = {})
114
- owner.processor_subscription(processor_id, options)
118
+ def processor_subscription(**options)
119
+ payment_processor.subscription(**options)
115
120
  end
116
121
 
117
122
  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('error-message').innerText = result.error.message;
16
+ document.getElementById("error-for-#{session.id}").innerText = result.error.message;
17
17
  }
18
18
  });
19
19
  });
@@ -0,0 +1,5 @@
1
+ class AddCurrencyToPayCharges < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :pay_charges, :currency, :string
4
+ end
5
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  class AddPayBillableTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
4
4
  def change
5
- change_table :<%= table_name %> do |t|
5
+ change_table :<%= table_name %>, bulk: true do |t|
6
6
  <%= migration_data -%>
7
7
  end
8
8
  end
@@ -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,
@@ -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
 
@@ -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
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 = owner_by_passtrough(event["passthrough"], event["subscription_plan_id"])
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
- return unless billable.present?
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)
data/lib/pay/stripe.rb CHANGED
@@ -11,6 +11,7 @@ module Pay
11
11
  autoload :CustomerDeleted, "pay/stripe/webhooks/customer_deleted"
12
12
  autoload :CustomerUpdated, "pay/stripe/webhooks/customer_updated"
13
13
  autoload :PaymentActionRequired, "pay/stripe/webhooks/payment_action_required"
14
+ autoload :PaymentIntentSucceeded, "pay/stripe/webhooks/payment_intent_succeeded"
14
15
  autoload :PaymentMethodUpdated, "pay/stripe/webhooks/payment_method_updated"
15
16
  autoload :SubscriptionCreated, "pay/stripe/webhooks/subscription_created"
16
17
  autoload :SubscriptionDeleted, "pay/stripe/webhooks/subscription_deleted"
@@ -50,6 +51,8 @@ module Pay
50
51
  events.subscribe "stripe.charge.succeeded", Pay::Stripe::Webhooks::ChargeSucceeded.new
51
52
  events.subscribe "stripe.charge.refunded", Pay::Stripe::Webhooks::ChargeRefunded.new
52
53
 
54
+ events.subscribe "stripe.payment_intent.succeeded", Pay::Stripe::Webhooks::PaymentIntentSucceeded.new
55
+
53
56
  # Warn user of upcoming charges for their subscription. This is handy for
54
57
  # notifying annual users their subscription will renew shortly.
55
58
  # This probably should be ignored for monthly subscriptions.
@@ -26,23 +26,22 @@ module Pay
26
26
  #
27
27
  # Returns Stripe::Customer
28
28
  def customer
29
- if processor_id?
29
+ stripe_customer = if processor_id?
30
30
  ::Stripe::Customer.retrieve(processor_id)
31
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
32
+ sc = ::Stripe::Customer.create(email: email, name: customer_name)
33
+ billable.update(processor: :stripe, processor_id: sc.id)
34
+ sc
35
+ end
43
36
 
44
- stripe_customer
37
+ # Update the user's card on file if a token was passed in
38
+ 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})
41
+ update_card_on_file(payment_method.card)
45
42
  end
43
+
44
+ stripe_customer
46
45
  rescue ::Stripe::StripeError => e
47
46
  raise Pay::Stripe::Error, e
48
47
  end
@@ -84,6 +83,7 @@ module Pay
84
83
  # Inherit trial from plan unless trial override was specified
85
84
  opts[:trial_from_plan] = true unless opts[:trial_period_days]
86
85
 
86
+ # Load the Stripe customer to verify it exists and update card if needed
87
87
  opts[:customer] = customer.id
88
88
 
89
89
  stripe_sub = ::Stripe::Subscription.create(opts)
@@ -198,8 +198,8 @@ module Pay
198
198
  payment_method_types: ["card"],
199
199
  mode: "payment",
200
200
  # These placeholder URLs will be replaced in a following step.
201
- success_url: root_url,
202
- cancel_url: root_url
201
+ success_url: options.delete(:success_url) || root_url,
202
+ cancel_url: options.delete(:cancel_url) || root_url
203
203
  }
204
204
 
205
205
  # Line items are optional
@@ -221,10 +221,11 @@ module Pay
221
221
  # checkout_charge(amount: 15_00, name: "T-shirt", quantity: 2)
222
222
  #
223
223
  def checkout_charge(amount:, name:, quantity: 1, **options)
224
+ currency = options.delete(:currency) || "usd"
224
225
  checkout(
225
226
  line_items: {
226
227
  price_data: {
227
- currency: options[:currency] || "usd",
228
+ currency: currency,
228
229
  product_data: {name: name},
229
230
  unit_amount: amount
230
231
  },
@@ -237,7 +238,7 @@ module Pay
237
238
  def billing_portal(**options)
238
239
  args = {
239
240
  customer: processor_id,
240
- return_url: options[:return_url] || root_url
241
+ return_url: options.delete(:return_url) || root_url
241
242
  }
242
243
  ::Stripe::BillingPortal::Session.create(args.merge(options))
243
244
  end
@@ -10,7 +10,7 @@ module Pay
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"])
14
14
  rescue ::Stripe::StripeError => e
15
15
  raise Pay::Stripe::Error, e
16
16
  end
@@ -23,6 +23,10 @@ module Pay
23
23
  @pay_subscription = pay_subscription
24
24
  end
25
25
 
26
+ def subscription(**options)
27
+ ::Stripe::Subscription.retrieve(options.merge(id: processor_id))
28
+ end
29
+
26
30
  def cancel
27
31
  subscription = processor_subscription
28
32
  subscription.cancel_at_period_end = true
@@ -41,6 +45,12 @@ module Pay
41
45
  raise Pay::Stripe::Error, e
42
46
  end
43
47
 
48
+ def change_quantity(quantity)
49
+ ::Stripe::Subscription.update(processor_id, quantity: quantity)
50
+ rescue ::Stripe::StripeError => e
51
+ raise Pay::Stripe::Error, e
52
+ end
53
+
44
54
  def on_grace_period?
45
55
  canceled? && Time.zone.now < ends_at
46
56
  end
@@ -0,0 +1,27 @@
1
+ module Pay
2
+ module Stripe
3
+ module Webhooks
4
+ class PaymentIntentSucceeded
5
+ def call(event)
6
+ object = event.data.object
7
+ billable = Pay.find_billable(processor: :stripe, processor_id: object.customer)
8
+
9
+ return unless billable.present?
10
+
11
+ object.charges.data.each do |charge|
12
+ next if billable.charges.where(processor_id: charge.id).any?
13
+
14
+ charge = Pay::Stripe::Billable.new(billable).save_pay_charge(charge)
15
+ notify_user(billable, charge)
16
+ end
17
+ end
18
+
19
+ def notify_user(billable, charge)
20
+ if Pay.send_emails && charge.respond_to?(:receipt)
21
+ Pay::UserMailer.with(billable: billable, charge: charge).receipt.deliver_later
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/pay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pay
2
- VERSION = "2.6.6"
2
+ VERSION = "2.6.11"
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.6
4
+ version: 2.6.11
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-03-30 00:00:00.000000000 Z
12
+ date: 2021-05-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -141,6 +141,7 @@ files:
141
141
  - db/migrate/20170727235816_create_pay_charges.rb
142
142
  - db/migrate/20190816015720_add_status_to_pay_subscriptions.rb
143
143
  - db/migrate/20200603134434_add_data_to_pay_models.rb
144
+ - db/migrate/20210423235138_add_currency_to_pay_charges.rb
144
145
  - lib/generators/active_record/pay_generator.rb
145
146
  - lib/generators/active_record/templates/migration.rb
146
147
  - lib/generators/pay/email_views_generator.rb
@@ -188,13 +189,13 @@ files:
188
189
  - lib/pay/stripe/billable.rb
189
190
  - lib/pay/stripe/charge.rb
190
191
  - lib/pay/stripe/error.rb
191
- - lib/pay/stripe/merchant.rb
192
192
  - lib/pay/stripe/subscription.rb
193
193
  - lib/pay/stripe/webhooks/charge_refunded.rb
194
194
  - lib/pay/stripe/webhooks/charge_succeeded.rb
195
195
  - lib/pay/stripe/webhooks/customer_deleted.rb
196
196
  - lib/pay/stripe/webhooks/customer_updated.rb
197
197
  - lib/pay/stripe/webhooks/payment_action_required.rb
198
+ - lib/pay/stripe/webhooks/payment_intent_succeeded.rb
198
199
  - lib/pay/stripe/webhooks/payment_method_updated.rb
199
200
  - lib/pay/stripe/webhooks/subscription_created.rb
200
201
  - lib/pay/stripe/webhooks/subscription_deleted.rb
@@ -1,28 +0,0 @@
1
- module Pay
2
- module Stripe
3
- module Merchant
4
- included do
5
- store_accessor :stripe_connect_account_id
6
- end
7
-
8
- def create_account(**options)
9
- defaults = {
10
- type: "standard"
11
- }
12
-
13
- stripe_account = ::Stripe::Account.create(defaults.merge(options))
14
- update(stripe_connect_account_id: stripe_account.id)
15
- stripe_account
16
- end
17
-
18
- def account_link(refresh_url:, return_url:, type: "account_onboarding", **options)
19
- Stripe::AccountLink.create({
20
- account: stripe_connect_account_id,
21
- refresh_url: refresh_url,
22
- return_url: return_url,
23
- type: type
24
- })
25
- end
26
- end
27
- end
28
- end