pay 11.7.2 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/app/controllers/pay/payments_controller.rb +2 -1
- data/app/models/pay/stripe/charge.rb +10 -3
- data/app/models/pay/stripe/customer.rb +4 -4
- data/app/models/pay/stripe/merchant.rb +1 -1
- data/app/models/pay/stripe/payment_method.rb +6 -3
- data/app/models/pay/stripe/subscription.rb +34 -21
- data/app/views/pay/payments/show.html.erb +1 -1
- data/app/views/pay/user_mailer/payment_action_required.html.erb +1 -1
- data/app/views/pay/user_mailer/payment_action_required.text.erb +1 -1
- data/lib/pay/payment.rb +9 -5
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +8 -4
- data/lib/pay/stripe/webhooks/invoice_updated.rb +4 -1
- data/lib/pay/stripe/webhooks/payment_action_required.rb +3 -2
- data/lib/pay/stripe.rb +1 -1
- data/lib/pay/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0d074d1f459f7129fb3f7e308075e87054d667f177453a89a08f3b243a4a029a
|
|
4
|
+
data.tar.gz: b6d3340eb343e55a964f925357076b76f751a2e1bae87fa262221682869cb9a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c5b8ad8fad63c66e64d5c4f03f06dd52b06e981342a1388a8b2ec405dd8438f3ba7cbc1256db54658d8e051e84370fb91806a8b3b916674d532c5ed048d5791f
|
|
7
|
+
data.tar.gz: cb8f4b0b6ec9450846a947876ac11da6b44d7bab9c595253179df16f50244d76413d491f2fc4ba25248b6101112ba5ba9ef406e1e95c8b6b418c792ed157442e
|
data/README.md
CHANGED
|
@@ -50,6 +50,7 @@ Want to add a new payment provider? Contributions are welcome.
|
|
|
50
50
|
* [Lemon Squeezy](docs/lemon_squeezy/1_overview.md)
|
|
51
51
|
* [Fake Processor](docs/fake_processor/1_overview.md)
|
|
52
52
|
* [Asaas (Community)](https://github.com/PedroAugustoRamalhoDuarte/pay-asaas)
|
|
53
|
+
* [Square (Community)](https://github.com/Willardgmoore/pay-square)
|
|
53
54
|
* **Marketplaces**
|
|
54
55
|
* [Stripe Connect](docs/marketplaces/stripe_connect.md)
|
|
55
56
|
* **Contributing**
|
|
@@ -4,8 +4,9 @@ module Pay
|
|
|
4
4
|
|
|
5
5
|
before_action :set_redirect_to
|
|
6
6
|
|
|
7
|
+
# Intents on a Stripe Connect account are linked with ?stripe_account=acct_123
|
|
7
8
|
def show
|
|
8
|
-
@payment = Payment.from_id(params[:id])
|
|
9
|
+
@payment = Payment.from_id(params[:id], stripe_account: params[:stripe_account].presence)
|
|
9
10
|
rescue ::Stripe::StripeError => e
|
|
10
11
|
redirect_to root_path, alert: e.message
|
|
11
12
|
end
|
|
@@ -27,6 +27,9 @@ module Pay
|
|
|
27
27
|
return
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# Requests for the rest of the sync should go to the same Stripe Connect account as the customer
|
|
31
|
+
stripe_account ||= pay_customer.stripe_account
|
|
32
|
+
|
|
30
33
|
payment_method = object.payment_method_details.try(object.payment_method_details.type)
|
|
31
34
|
attrs = {
|
|
32
35
|
object: object.to_hash,
|
|
@@ -42,7 +45,7 @@ module Pay
|
|
|
42
45
|
last4: payment_method.try(:last4).to_s,
|
|
43
46
|
metadata: object.metadata,
|
|
44
47
|
payment_method_type: object.payment_method_details.type,
|
|
45
|
-
stripe_account:
|
|
48
|
+
stripe_account: stripe_account,
|
|
46
49
|
stripe_receipt_url: object.receipt_url
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -72,7 +75,7 @@ module Pay
|
|
|
72
75
|
raise
|
|
73
76
|
else
|
|
74
77
|
try += 1
|
|
75
|
-
sleep 0.15
|
|
78
|
+
sleep 0.15 * try
|
|
76
79
|
retry
|
|
77
80
|
end
|
|
78
81
|
end
|
|
@@ -124,7 +127,7 @@ module Pay
|
|
|
124
127
|
raise Pay::Stripe::Error, "no payment_intent on charge" unless payment_intent.present?
|
|
125
128
|
payment_intent_id = payment_intent.is_a?(::Stripe::PaymentIntent) ? payment_intent.id : payment_intent
|
|
126
129
|
::Stripe::PaymentIntent.capture(payment_intent_id, options, stripe_options)
|
|
127
|
-
self.class.sync(processor_id)
|
|
130
|
+
self.class.sync(processor_id, stripe_account: stripe_account)
|
|
128
131
|
rescue ::Stripe::StripeError => e
|
|
129
132
|
raise Pay::Stripe::Error, e
|
|
130
133
|
end
|
|
@@ -144,6 +147,10 @@ module Pay
|
|
|
144
147
|
::Stripe::Charge.construct_from(object)
|
|
145
148
|
end
|
|
146
149
|
|
|
150
|
+
def sync!(**options)
|
|
151
|
+
super(**options.with_defaults(stripe_account: stripe_account))
|
|
152
|
+
end
|
|
153
|
+
|
|
147
154
|
private
|
|
148
155
|
|
|
149
156
|
# Options for Stripe requests
|
|
@@ -50,7 +50,7 @@ module Pay
|
|
|
50
50
|
Pay::Payment.new(payment_intent).validate
|
|
51
51
|
|
|
52
52
|
charge = payment_intent.latest_charge
|
|
53
|
-
Pay::Stripe::Charge.sync(charge.id, object: charge)
|
|
53
|
+
Pay::Stripe::Charge.sync(charge.id, object: charge, stripe_account: stripe_account)
|
|
54
54
|
rescue ::Stripe::StripeError => e
|
|
55
55
|
raise Pay::Stripe::Error, e
|
|
56
56
|
end
|
|
@@ -73,7 +73,7 @@ module Pay
|
|
|
73
73
|
# No trial, payment method requires SCA
|
|
74
74
|
if options[:payment_behavior].to_s != "default_incomplete" && subscription.incomplete?
|
|
75
75
|
payment_intent_id = stripe_sub.latest_invoice.payments.first.payment.payment_intent
|
|
76
|
-
Pay::Payment.from_id(payment_intent_id).validate
|
|
76
|
+
Pay::Payment.from_id(payment_intent_id, stripe_account: stripe_account).validate
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
subscription
|
|
@@ -151,7 +151,7 @@ module Pay
|
|
|
151
151
|
def sync_subscriptions(**options)
|
|
152
152
|
subscriptions = ::Stripe::Subscription.list(options.with_defaults(customer: processor_id), stripe_options)
|
|
153
153
|
subscriptions.map do |subscription|
|
|
154
|
-
Pay::Stripe::Subscription.sync(subscription.id)
|
|
154
|
+
Pay::Stripe::Subscription.sync(subscription.id, stripe_account: stripe_account)
|
|
155
155
|
end
|
|
156
156
|
rescue ::Stripe::StripeError => e
|
|
157
157
|
raise Pay::Stripe::Error, e
|
|
@@ -251,7 +251,7 @@ module Pay
|
|
|
251
251
|
::Stripe::Billing::MeterEvent.create({
|
|
252
252
|
event_name: event_name,
|
|
253
253
|
payload: {stripe_customer_id: processor_id}.merge(payload)
|
|
254
|
-
}.merge(options))
|
|
254
|
+
}.merge(options), stripe_options)
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
private
|
|
@@ -28,7 +28,7 @@ module Pay
|
|
|
28
28
|
|
|
29
29
|
# A single-use login link for Express accounts to access their Stripe dashboard
|
|
30
30
|
def login_link(**options)
|
|
31
|
-
::Stripe::Account.create_login_link(processor_id)
|
|
31
|
+
::Stripe::Account.create_login_link(processor_id, options)
|
|
32
32
|
rescue ::Stripe::StripeError => e
|
|
33
33
|
raise Pay::Stripe::Error, e
|
|
34
34
|
end
|
|
@@ -6,7 +6,7 @@ module Pay
|
|
|
6
6
|
payment_intent = ::Stripe::PaymentIntent.retrieve({id: id, expand: ["payment_method"]}, {stripe_account: stripe_account}.compact)
|
|
7
7
|
payment_method = payment_intent.payment_method
|
|
8
8
|
return unless payment_method
|
|
9
|
-
Pay::Stripe::PaymentMethod.sync(payment_method.id, object: payment_method)
|
|
9
|
+
Pay::Stripe::PaymentMethod.sync(payment_method.id, object: payment_method, stripe_account: stripe_account)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# Syncs a SetupIntent's payment method to the database
|
|
@@ -14,7 +14,7 @@ module Pay
|
|
|
14
14
|
setup_intent = ::Stripe::SetupIntent.retrieve({id: id, expand: ["payment_method"]}, {stripe_account: stripe_account}.compact)
|
|
15
15
|
payment_method = setup_intent.payment_method
|
|
16
16
|
return unless payment_method
|
|
17
|
-
Pay::Stripe::PaymentMethod.sync(payment_method.id, object: payment_method)
|
|
17
|
+
Pay::Stripe::PaymentMethod.sync(payment_method.id, object: payment_method, stripe_account: stripe_account)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# Syncs PaymentMethod objects from Stripe
|
|
@@ -31,6 +31,9 @@ module Pay
|
|
|
31
31
|
return
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
# Record the same Stripe Connect account as the customer when one wasn't given
|
|
35
|
+
stripe_account ||= pay_customer.stripe_account
|
|
36
|
+
|
|
34
37
|
default_payment_method_id = pay_customer.api_record.invoice_settings&.default_payment_method
|
|
35
38
|
default = (id == default_payment_method_id)
|
|
36
39
|
|
|
@@ -45,7 +48,7 @@ module Pay
|
|
|
45
48
|
raise
|
|
46
49
|
else
|
|
47
50
|
try += 1
|
|
48
|
-
sleep 0.15
|
|
51
|
+
sleep 0.15 * try
|
|
49
52
|
retry
|
|
50
53
|
end
|
|
51
54
|
end
|
|
@@ -5,7 +5,7 @@ module Pay
|
|
|
5
5
|
|
|
6
6
|
def self.sync_from_checkout_session(session_id, stripe_account: nil)
|
|
7
7
|
checkout_session = ::Stripe::Checkout::Session.retrieve({id: session_id}, {stripe_account: stripe_account}.compact)
|
|
8
|
-
sync(checkout_session.subscription)
|
|
8
|
+
sync(checkout_session.subscription, stripe_account: stripe_account)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def self.sync(subscription_id, object: nil, name: nil, stripe_account: nil, try: 0, retries: 1)
|
|
@@ -22,6 +22,9 @@ module Pay
|
|
|
22
22
|
return
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# Requests for the rest of the sync should go to the same Stripe Connect account as the customer
|
|
26
|
+
stripe_account ||= pay_customer.stripe_account
|
|
27
|
+
|
|
25
28
|
attributes = {
|
|
26
29
|
object: object.to_hash,
|
|
27
30
|
application_fee_percent: object.application_fee_percent,
|
|
@@ -29,7 +32,7 @@ module Pay
|
|
|
29
32
|
processor_plan: object.items.first.price.id,
|
|
30
33
|
quantity: object.items.first.try(:quantity) || 0,
|
|
31
34
|
status: object.status,
|
|
32
|
-
stripe_account:
|
|
35
|
+
stripe_account: stripe_account,
|
|
33
36
|
metadata: object.metadata,
|
|
34
37
|
metered: false,
|
|
35
38
|
pause_behavior: object.pause_collection&.behavior,
|
|
@@ -70,10 +73,10 @@ module Pay
|
|
|
70
73
|
# Sync payment method if directly attached to subscription
|
|
71
74
|
if object.default_payment_method
|
|
72
75
|
if object.default_payment_method.is_a? String
|
|
73
|
-
Pay::Stripe::PaymentMethod.sync(object.default_payment_method)
|
|
76
|
+
Pay::Stripe::PaymentMethod.sync(object.default_payment_method, stripe_account: stripe_account)
|
|
74
77
|
attributes[:payment_method_id] = object.default_payment_method
|
|
75
78
|
else
|
|
76
|
-
Pay::Stripe::PaymentMethod.sync(object.default_payment_method.id, object: object.default_payment_method)
|
|
79
|
+
Pay::Stripe::PaymentMethod.sync(object.default_payment_method.id, object: object.default_payment_method, stripe_account: stripe_account)
|
|
77
80
|
attributes[:payment_method_id] = object.default_payment_method.id
|
|
78
81
|
end
|
|
79
82
|
end
|
|
@@ -106,9 +109,9 @@ module Pay
|
|
|
106
109
|
|
|
107
110
|
case invoice_payment.payment.type
|
|
108
111
|
when "payment_intent"
|
|
109
|
-
Pay::Stripe::Charge.sync_payment_intent(invoice_payment.payment.payment_intent, stripe_account:
|
|
112
|
+
Pay::Stripe::Charge.sync_payment_intent(invoice_payment.payment.payment_intent, stripe_account: stripe_account)
|
|
110
113
|
when "charge"
|
|
111
|
-
Pay::Stripe::Charge.sync(invoice_payment.payment.charge, stripe_account:
|
|
114
|
+
Pay::Stripe::Charge.sync(invoice_payment.payment.charge, stripe_account: stripe_account)
|
|
112
115
|
end
|
|
113
116
|
end
|
|
114
117
|
end
|
|
@@ -144,6 +147,10 @@ module Pay
|
|
|
144
147
|
::Stripe::Subscription.construct_from(object)
|
|
145
148
|
end
|
|
146
149
|
|
|
150
|
+
def sync!(**options)
|
|
151
|
+
super(**options.with_defaults(stripe_account: stripe_account))
|
|
152
|
+
end
|
|
153
|
+
|
|
147
154
|
def api_record(**options)
|
|
148
155
|
@api_record ||= ::Stripe::Subscription.retrieve(options.with_defaults(id: processor_id).merge(expand_options), {stripe_account: stripe_account}.compact)
|
|
149
156
|
end
|
|
@@ -198,16 +205,12 @@ module Pay
|
|
|
198
205
|
|
|
199
206
|
# This updates a SubscriptionItem's quantity in Stripe
|
|
200
207
|
#
|
|
201
|
-
#
|
|
202
|
-
#
|
|
208
|
+
# Defaults to the first SubscriptionItem. Pass subscription_item_id: to update a different one
|
|
209
|
+
# (Stripe no longer accepts a top-level quantity on the subscription itself)
|
|
203
210
|
def change_quantity(quantity, **options)
|
|
204
|
-
subscription_item_id = options.delete(:subscription_item_id) || subscription_items
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@api_record = nil
|
|
208
|
-
else
|
|
209
|
-
@api_record = ::Stripe::Subscription.update(processor_id, options.merge(quantity: quantity).merge(expand_options), stripe_options)
|
|
210
|
-
end
|
|
211
|
+
subscription_item_id = options.delete(:subscription_item_id) || subscription_items.first.id
|
|
212
|
+
::Stripe::SubscriptionItem.update(subscription_item_id, options.merge(quantity: quantity), stripe_options)
|
|
213
|
+
@api_record = nil
|
|
211
214
|
update(quantity: quantity)
|
|
212
215
|
rescue ::Stripe::StripeError => e
|
|
213
216
|
raise Pay::Stripe::Error, e
|
|
@@ -285,7 +288,7 @@ module Pay
|
|
|
285
288
|
}.merge(expand_options),
|
|
286
289
|
stripe_options)
|
|
287
290
|
end
|
|
288
|
-
update(ends_at: nil, status:
|
|
291
|
+
update(ends_at: nil, status: @api_record.status)
|
|
289
292
|
rescue ::Stripe::StripeError => e
|
|
290
293
|
raise Pay::Stripe::Error, e
|
|
291
294
|
end
|
|
@@ -309,7 +312,7 @@ module Pay
|
|
|
309
312
|
|
|
310
313
|
# Validate that swap was successful and handle SCA if needed
|
|
311
314
|
if (payment_intent_id = @api_record.latest_invoice.payments.first&.payment&.payment_intent)
|
|
312
|
-
Pay::Payment.from_id(payment_intent_id).validate
|
|
315
|
+
Pay::Payment.from_id(payment_intent_id, stripe_account: stripe_account).validate
|
|
313
316
|
end
|
|
314
317
|
|
|
315
318
|
sync!(object: @api_record)
|
|
@@ -338,7 +341,10 @@ module Pay
|
|
|
338
341
|
payment_intent = ::Stripe::PaymentIntent.retrieve({id: payment_intent_id}, stripe_options)
|
|
339
342
|
|
|
340
343
|
payment_intent = if payment_intent.status == "requires_payment_method"
|
|
341
|
-
|
|
344
|
+
payment_method = customer.default_payment_method
|
|
345
|
+
raise Pay::Stripe::Error, "no default payment method to retry the payment with" if payment_method.nil?
|
|
346
|
+
|
|
347
|
+
::Stripe::PaymentIntent.confirm(payment_intent_id, {payment_method: payment_method.processor_id}, stripe_options)
|
|
342
348
|
else
|
|
343
349
|
::Stripe::PaymentIntent.confirm(payment_intent_id, stripe_options)
|
|
344
350
|
end
|
|
@@ -348,14 +354,21 @@ module Pay
|
|
|
348
354
|
end
|
|
349
355
|
|
|
350
356
|
# Looks up open invoices for a subscription and attempts to pay them
|
|
357
|
+
#
|
|
358
|
+
# Invoices no longer expose a `payment_intent` directly, so the PaymentIntent is looked up through the invoice's payments
|
|
351
359
|
def pay_open_invoices
|
|
352
|
-
::Stripe::Invoice.list({subscription: processor_id, status: :open}, stripe_options).auto_paging_each do |invoice|
|
|
353
|
-
|
|
360
|
+
::Stripe::Invoice.list({subscription: processor_id, status: :open, expand: ["data.payments"]}, stripe_options).auto_paging_each do |invoice|
|
|
361
|
+
payment_intent_id = invoice.payments.first&.payment&.payment_intent
|
|
362
|
+
retry_failed_payment(payment_intent_id: payment_intent_id) if payment_intent_id
|
|
354
363
|
end
|
|
355
364
|
end
|
|
356
365
|
|
|
366
|
+
# Returns the Stripe::PaymentIntent for the latest invoice, if there is one
|
|
357
367
|
def latest_payment
|
|
358
|
-
api_record
|
|
368
|
+
payment_intent_id = api_record.latest_invoice&.payments&.first&.payment&.payment_intent
|
|
369
|
+
::Stripe::PaymentIntent.retrieve({id: payment_intent_id}, stripe_options) if payment_intent_id
|
|
370
|
+
rescue ::Stripe::StripeError => e
|
|
371
|
+
raise Pay::Stripe::Error, e
|
|
359
372
|
end
|
|
360
373
|
|
|
361
374
|
private
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
</div>
|
|
65
65
|
|
|
66
66
|
<script type="module">
|
|
67
|
-
window.stripe = Stripe('<%= Pay::Stripe.public_key %>')
|
|
67
|
+
window.stripe = Stripe('<%= Pay::Stripe.public_key %>', <%= {stripeAccount: @payment.stripe_account}.compact.to_json.html_safe %>)
|
|
68
68
|
|
|
69
69
|
import { Application, Controller } from 'https://unpkg.com/@hotwired/stimulus/dist/stimulus.js'
|
|
70
70
|
const application = Application.start()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<h3>Extra confirmation is needed to process your payment</h3>
|
|
2
2
|
<p>Your <%= Pay.application_name %> subscription requires confirmation to process your payment to continue access.</p>
|
|
3
|
-
<p><%= link_to "Confirm your payment", pay.payment_url(params[:payment_intent_id]) %></p>
|
|
3
|
+
<p><%= link_to "Confirm your payment", pay.payment_url(params[:payment_intent_id], stripe_account: params[:stripe_account]) %></p>
|
|
4
4
|
<p>If you have any questions, please hit reply and let us know.</p>
|
|
5
5
|
<p>— The <%= Pay.application_name %> Team</p>
|
|
@@ -2,7 +2,7 @@ Extra confirmation is needed to process your payment
|
|
|
2
2
|
|
|
3
3
|
Your <%= Pay.application_name %> subscription requires confirmation to process your payment to continue access.
|
|
4
4
|
|
|
5
|
-
Confirm your payment: <%= pay.payment_url(params[:payment_intent_id]) %>
|
|
5
|
+
Confirm your payment: <%= pay.payment_url(params[:payment_intent_id], stripe_account: params[:stripe_account]) %>
|
|
6
6
|
|
|
7
7
|
If you have any questions, please hit reply and let us know.
|
|
8
8
|
|
data/lib/pay/payment.rb
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
module Pay
|
|
2
2
|
class Payment
|
|
3
|
-
|
|
3
|
+
# The Stripe Connect account the intent lives on, if any. Needed to look the intent up again
|
|
4
|
+
# and to initialize Stripe.js on the SCA confirmation page.
|
|
5
|
+
attr_reader :intent, :stripe_account
|
|
4
6
|
|
|
5
7
|
delegate :id, :amount, :client_secret, :currency, :customer, :status, :confirm, to: :intent
|
|
6
8
|
|
|
7
|
-
def self.from_id(id)
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
def self.from_id(id, stripe_account: nil)
|
|
10
|
+
options = {stripe_account: stripe_account}.compact
|
|
11
|
+
intent = id.start_with?("seti_") ? ::Stripe::SetupIntent.retrieve(id, options) : ::Stripe::PaymentIntent.retrieve(id, options)
|
|
12
|
+
new(intent, stripe_account: stripe_account)
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
def initialize(intent)
|
|
15
|
+
def initialize(intent, stripe_account: nil)
|
|
13
16
|
@intent = intent
|
|
17
|
+
@stripe_account = stripe_account
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
def requires_payment_method?
|
|
@@ -3,7 +3,7 @@ module Pay
|
|
|
3
3
|
module Webhooks
|
|
4
4
|
class CheckoutSessionCompleted
|
|
5
5
|
def call(event)
|
|
6
|
-
locate_owner(event.data.object)
|
|
6
|
+
locate_owner(event.data.object, stripe_account: event.try(:account))
|
|
7
7
|
|
|
8
8
|
# By the time CheckoutSessionCompleted is fired, we probably missed the original events
|
|
9
9
|
# Instead, we can sync the payment intent or subscription during this event to ensure they're in the database
|
|
@@ -18,11 +18,15 @@ module Pay
|
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
# Associates the Stripe customer from the session with the record referenced by client_reference_id
|
|
22
|
+
#
|
|
23
|
+
# Sessions in payment or setup mode don't always create a Stripe customer (for example Payment Links with
|
|
24
|
+
# customer_creation: if_required), so skip those rather than clearing an existing processor_id
|
|
25
|
+
def locate_owner(object, stripe_account: nil)
|
|
26
|
+
return if object.client_reference_id.nil? || object.customer.nil?
|
|
23
27
|
|
|
24
28
|
owner = Pay::Stripe.find_by_client_reference_id(object.client_reference_id)
|
|
25
|
-
owner&.add_payment_processor(:stripe, processor_id: object.customer)
|
|
29
|
+
owner&.add_payment_processor(:stripe, processor_id: object.customer, stripe_account: stripe_account)
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
end
|
|
@@ -19,10 +19,13 @@ module Pay
|
|
|
19
19
|
return unless subscription
|
|
20
20
|
|
|
21
21
|
# Grab the local latest_invoice from the subscription stripe_object
|
|
22
|
+
# It may be an expanded object, a bare ID, or nil for a subscription that hasn't been invoiced yet
|
|
22
23
|
latest_invoice = subscription.stripe_object.try(:latest_invoice)
|
|
24
|
+
latest_invoice_id = latest_invoice.try(:id) || latest_invoice
|
|
25
|
+
return if latest_invoice_id.blank?
|
|
23
26
|
|
|
24
27
|
# Compare the local invoice id to the event invoice id and sync if they are the same
|
|
25
|
-
if
|
|
28
|
+
if latest_invoice_id.to_s == invoice.id.to_s
|
|
26
29
|
Pay::Stripe::Subscription.sync(subscription_id, stripe_account: event.try(:account))
|
|
27
30
|
end
|
|
28
31
|
rescue ::Stripe::StripeError => e
|
|
@@ -13,13 +13,14 @@ module Pay
|
|
|
13
13
|
pay_subscription = Pay::Subscription.find_by_processor_and_id(:stripe, subscription_id)
|
|
14
14
|
return if pay_subscription.nil? || pay_subscription.status == "incomplete"
|
|
15
15
|
|
|
16
|
-
invoice_payment = ::Stripe::InvoicePayment.list({invoice: invoice.id, status: :open}).first
|
|
16
|
+
invoice_payment = ::Stripe::InvoicePayment.list({invoice: invoice.id, status: :open}, {stripe_account: event.try(:account)}.compact).first
|
|
17
17
|
|
|
18
18
|
if invoice_payment && Pay.send_email?(:payment_action_required, pay_subscription)
|
|
19
19
|
Pay.mailer.with(
|
|
20
20
|
pay_customer: pay_subscription.customer,
|
|
21
21
|
pay_subscription: pay_subscription,
|
|
22
|
-
payment_intent_id: invoice_payment.payment.payment_intent
|
|
22
|
+
payment_intent_id: invoice_payment.payment.payment_intent,
|
|
23
|
+
stripe_account: event.try(:account)
|
|
23
24
|
).payment_action_required.deliver_later
|
|
24
25
|
end
|
|
25
26
|
end
|
data/lib/pay/stripe.rb
CHANGED
data/lib/pay/version.rb
CHANGED