pay 12.1.1 → 12.3.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/app/models/pay/paddle_billing/customer.rb +2 -2
- data/app/models/pay/paddle_billing/subscription.rb +26 -15
- data/app/models/pay/paddle_classic/customer.rb +1 -1
- data/app/models/pay/paddle_classic/payment_method.rb +1 -1
- data/app/models/pay/paddle_classic/subscription.rb +6 -6
- data/app/models/pay/stripe/customer.rb +1 -1
- data/app/models/pay/stripe/subscription.rb +41 -7
- data/app/views/pay/payments/show.html.erb +22 -11
- data/config/locales/en.yml +12 -0
- data/lib/pay/paddle_billing.rb +4 -2
- data/lib/pay/paddle_classic.rb +4 -2
- data/lib/pay/payment.rb +6 -0
- data/lib/pay/stripe.rb +1 -1
- data/lib/pay/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f77372d0f6b47b272a614d14cd91183c86b56dd02d2ecea25fd99ebccde3ec7b
|
|
4
|
+
data.tar.gz: 7c6c0b2196445b486b0519a14c1fe1a1123c81316822af0cc2fea3c891c731dd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e30e10e229a3af4a2dea25d532c209831c9388222226d97b1c576e4ddf3aee7509da290a2fa6f762dd6a687bea07962e5c309c22ce1cca84a337d6edc979057c
|
|
7
|
+
data.tar.gz: 4878549cc6eb89db69734ae9bbec6d2e9fa4d6027322af4e266e89c5a026ebb19c946a202b63327f55c3b3da8b9384112ace9310effe1c9552a4ede2efef0516
|
|
@@ -27,7 +27,7 @@ module Pay
|
|
|
27
27
|
update!(processor_id: pc.id)
|
|
28
28
|
pc
|
|
29
29
|
end
|
|
30
|
-
rescue ::Paddle::
|
|
30
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
31
31
|
raise Pay::PaddleBilling::Error, e
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -55,7 +55,7 @@ module Pay
|
|
|
55
55
|
charge = charges.find_or_initialize_by(processor_id: transaction.id)
|
|
56
56
|
charge.update(attrs)
|
|
57
57
|
charge
|
|
58
|
-
rescue ::Paddle::
|
|
58
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
59
59
|
raise Pay::PaddleBilling::Error, e
|
|
60
60
|
end
|
|
61
61
|
|
|
@@ -39,8 +39,6 @@ module Pay
|
|
|
39
39
|
pay_customer.payment_methods.destroy_all
|
|
40
40
|
when "trialing"
|
|
41
41
|
attributes[:trial_ends_at] = Time.parse(subscription.next_billed_at) if subscription.next_billed_at
|
|
42
|
-
when "paused"
|
|
43
|
-
attributes[:pause_starts_at] = Time.parse(subscription.paused_at) if subscription.paused_at
|
|
44
42
|
when "active", "past_due"
|
|
45
43
|
attributes[:trial_ends_at] = nil
|
|
46
44
|
attributes[:pause_starts_at] = nil
|
|
@@ -76,10 +74,12 @@ module Pay
|
|
|
76
74
|
end
|
|
77
75
|
|
|
78
76
|
# If a subscription is paused, cancel immediately
|
|
79
|
-
# Otherwise, cancel at period end
|
|
77
|
+
# Otherwise, cancel at period end. A scheduled pause is removed first
|
|
80
78
|
def cancel(**options)
|
|
81
79
|
return if canceled?
|
|
82
80
|
|
|
81
|
+
remove_scheduled_pause if will_pause?
|
|
82
|
+
|
|
83
83
|
response = ::Paddle::Subscription.cancel(
|
|
84
84
|
id: processor_id,
|
|
85
85
|
effective_from: options.fetch(:effective_from, paused? ? "immediately" : "next_billing_period")
|
|
@@ -88,14 +88,12 @@ module Pay
|
|
|
88
88
|
status: response.status,
|
|
89
89
|
ends_at: response.scheduled_change&.effective_at || Time.current
|
|
90
90
|
)
|
|
91
|
-
rescue ::Paddle::
|
|
91
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
92
92
|
raise Pay::PaddleBilling::Error, e
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
def cancel_now!(**options)
|
|
96
96
|
cancel(**options.merge(effective_from: "immediately"))
|
|
97
|
-
rescue ::Paddle::Error => e
|
|
98
|
-
raise Pay::PaddleBilling::Error, e
|
|
99
97
|
end
|
|
100
98
|
|
|
101
99
|
def change_quantity(quantity, **options)
|
|
@@ -110,24 +108,30 @@ module Pay
|
|
|
110
108
|
proration_billing_mode: options.delete(:proration_billing_mode) || "prorated_immediately"
|
|
111
109
|
)
|
|
112
110
|
update(quantity: quantity)
|
|
113
|
-
rescue ::Paddle::
|
|
111
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
114
112
|
raise Pay::PaddleBilling::Error, e
|
|
115
113
|
end
|
|
116
114
|
|
|
117
115
|
# A subscription could be set to cancel or pause in the future
|
|
118
116
|
# It is considered on grace period until the cancel or pause time begins
|
|
119
117
|
def on_grace_period?
|
|
120
|
-
(canceled? &&
|
|
118
|
+
(canceled? && ends_at.future?) || will_pause?
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def will_pause?
|
|
122
|
+
pause_starts_at? && pause_starts_at.future?
|
|
121
123
|
end
|
|
122
124
|
|
|
125
|
+
# Paddle keeps the status `active` until a scheduled pause starts, so check pause_starts_at as well
|
|
123
126
|
def paused?
|
|
124
|
-
status == "paused"
|
|
127
|
+
status == "paused" || pause_starts_at?
|
|
125
128
|
end
|
|
126
129
|
|
|
130
|
+
# Pauses the subscription at the end of the current billing period
|
|
127
131
|
def pause
|
|
128
132
|
response = ::Paddle::Subscription.pause(id: processor_id)
|
|
129
|
-
update!(status:
|
|
130
|
-
rescue ::Paddle::
|
|
133
|
+
update!(status: response.status, pause_starts_at: response.scheduled_change.effective_at)
|
|
134
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
131
135
|
raise Pay::PaddleBilling::Error, e
|
|
132
136
|
end
|
|
133
137
|
|
|
@@ -141,15 +145,14 @@ module Pay
|
|
|
141
145
|
end
|
|
142
146
|
|
|
143
147
|
# Paddle Billing API only allows "resuming" subscriptions when they are paused
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
::Paddle::Subscription.update(id: processor_id, scheduled_change: nil)
|
|
148
|
+
if will_pause?
|
|
149
|
+
remove_scheduled_pause
|
|
147
150
|
else
|
|
148
151
|
::Paddle::Subscription.resume(id: processor_id, effective_from: "immediately")
|
|
149
152
|
end
|
|
150
153
|
|
|
151
154
|
update(ends_at: nil, status: :active, pause_starts_at: nil)
|
|
152
|
-
rescue ::Paddle::
|
|
155
|
+
rescue ::Paddle::ErrorGenerator => e
|
|
153
156
|
raise Pay::PaddleBilling::Error, e
|
|
154
157
|
end
|
|
155
158
|
|
|
@@ -168,6 +171,14 @@ module Pay
|
|
|
168
171
|
)
|
|
169
172
|
update(processor_plan: plan, ends_at: nil, status: :active)
|
|
170
173
|
end
|
|
174
|
+
|
|
175
|
+
private
|
|
176
|
+
|
|
177
|
+
# Paddle rejects changes to a subscription with a scheduled change
|
|
178
|
+
def remove_scheduled_pause
|
|
179
|
+
::Paddle::Subscription.update(id: processor_id, scheduled_change: nil)
|
|
180
|
+
update!(pause_starts_at: nil)
|
|
181
|
+
end
|
|
171
182
|
end
|
|
172
183
|
end
|
|
173
184
|
end
|
|
@@ -54,7 +54,7 @@ module Pay
|
|
|
54
54
|
|
|
55
55
|
def api_record(**options)
|
|
56
56
|
PaddleClassic.client.users.list(subscription_id: processor_id).data.try(:first)
|
|
57
|
-
rescue ::Paddle::Error => e
|
|
57
|
+
rescue ::Paddle::Classic::Error => e
|
|
58
58
|
raise Pay::PaddleClassic::Error, e
|
|
59
59
|
end
|
|
60
60
|
|
|
@@ -78,7 +78,7 @@ module Pay
|
|
|
78
78
|
|
|
79
79
|
# Remove payment methods since customer cannot be reused after cancelling
|
|
80
80
|
Pay::PaymentMethod.where(customer_id: customer_id).destroy_all
|
|
81
|
-
rescue ::Paddle::Error => e
|
|
81
|
+
rescue ::Paddle::Classic::Error => e
|
|
82
82
|
raise Pay::PaddleClassic::Error, e
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -90,7 +90,7 @@ module Pay
|
|
|
90
90
|
|
|
91
91
|
# Remove payment methods since customer cannot be reused after cancelling
|
|
92
92
|
Pay::PaymentMethod.where(customer_id: customer_id).destroy_all
|
|
93
|
-
rescue ::Paddle::Error => e
|
|
93
|
+
rescue ::Paddle::Classic::Error => e
|
|
94
94
|
raise Pay::PaddleClassic::Error, e
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -111,7 +111,7 @@ module Pay
|
|
|
111
111
|
def pause
|
|
112
112
|
response = PaddleClassic.client.users.pause(subscription_id: processor_id)
|
|
113
113
|
update(status: :paused, pause_starts_at: Time.zone.parse(response.dig(:next_payment, :date)))
|
|
114
|
-
rescue ::Paddle::Error => e
|
|
114
|
+
rescue ::Paddle::Classic::Error => e
|
|
115
115
|
raise Pay::PaddleClassic::Error, e
|
|
116
116
|
end
|
|
117
117
|
|
|
@@ -126,7 +126,7 @@ module Pay
|
|
|
126
126
|
|
|
127
127
|
PaddleClassic.client.users.unpause(subscription_id: processor_id)
|
|
128
128
|
update(ends_at: nil, status: :active, pause_starts_at: nil)
|
|
129
|
-
rescue ::Paddle::Error => e
|
|
129
|
+
rescue ::Paddle::Classic::Error => e
|
|
130
130
|
raise Pay::PaddleClassic::Error, e
|
|
131
131
|
end
|
|
132
132
|
|
|
@@ -138,7 +138,7 @@ module Pay
|
|
|
138
138
|
PaddleClassic.client.users.update(subscription_id: processor_id, **attributes)
|
|
139
139
|
|
|
140
140
|
update(processor_plan: plan, ends_at: nil, status: :active)
|
|
141
|
-
rescue ::Paddle::Error => e
|
|
141
|
+
rescue ::Paddle::Classic::Error => e
|
|
142
142
|
raise Pay::PaddleClassic::Error, e
|
|
143
143
|
end
|
|
144
144
|
end
|
|
@@ -133,7 +133,7 @@ module Pay
|
|
|
133
133
|
|
|
134
134
|
# Used for creating Stripe Terminal charges
|
|
135
135
|
def terminal_charge(amount, options = {})
|
|
136
|
-
create_payment_intent(amount, options.merge(
|
|
136
|
+
create_payment_intent(amount, options.merge(allowed_payment_method_types: ["card_present"], capture_method: "manual"))
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
def create_setup_intent(options = {})
|
|
@@ -217,7 +217,7 @@ module Pay
|
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
def paused?
|
|
220
|
-
|
|
220
|
+
status_paused? || pause_behavior_void?
|
|
221
221
|
end
|
|
222
222
|
|
|
223
223
|
# Pauses a Stripe subscription
|
|
@@ -266,12 +266,22 @@ module Pay
|
|
|
266
266
|
on_grace_period? || paused?
|
|
267
267
|
end
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
# Resumes a subscription that is on its grace period or paused
|
|
270
|
+
#
|
|
271
|
+
# Subscriptions with a `paused` status are billed immediately and stay paused until that invoice is paid
|
|
272
|
+
# Raises Pay::InvalidPaymentMethod or Pay::ActionRequired if that payment needs a payment method or authentication
|
|
273
|
+
#
|
|
274
|
+
# resume(billing_cycle_anchor: "unchanged")
|
|
275
|
+
#
|
|
276
|
+
# https://docs.stripe.com/api/subscriptions/resume
|
|
277
|
+
def resume(**options)
|
|
270
278
|
unless resumable?
|
|
271
|
-
raise Error, "You can only resume subscriptions within their grace period."
|
|
279
|
+
raise Error, "You can only resume subscriptions that are paused or within their grace period."
|
|
272
280
|
end
|
|
273
281
|
|
|
274
|
-
if
|
|
282
|
+
if status_paused?
|
|
283
|
+
@api_record = ::Stripe::Subscription.resume(processor_id, options.merge(expand_options), stripe_options)
|
|
284
|
+
elsif paused?
|
|
275
285
|
unpause
|
|
276
286
|
else
|
|
277
287
|
@api_record = ::Stripe::Subscription.update(processor_id, {
|
|
@@ -281,6 +291,10 @@ module Pay
|
|
|
281
291
|
stripe_options)
|
|
282
292
|
end
|
|
283
293
|
update(ends_at: nil, status: @api_record.status)
|
|
294
|
+
|
|
295
|
+
# Stripe resumes successfully even when the payment fails, leaving the subscription paused
|
|
296
|
+
validate_latest_payment if status_paused?
|
|
297
|
+
true
|
|
284
298
|
rescue ::Stripe::StripeError => e
|
|
285
299
|
raise Pay::Stripe::Error, e
|
|
286
300
|
end
|
|
@@ -291,6 +305,11 @@ module Pay
|
|
|
291
305
|
prorate = options.delete(:prorate) { true }
|
|
292
306
|
proration_behavior = options.delete(:proration_behavior) || (prorate ? "always_invoice" : "none")
|
|
293
307
|
|
|
308
|
+
# Stripe 20 takes billing_cycle_anchor as {type: "now"} on updates, so convert the old "now" / "unchanged" form
|
|
309
|
+
if options[:billing_cycle_anchor].is_a?(String) || options[:billing_cycle_anchor].is_a?(Symbol)
|
|
310
|
+
options[:billing_cycle_anchor] = {type: options[:billing_cycle_anchor].to_s}
|
|
311
|
+
end
|
|
312
|
+
|
|
294
313
|
@api_record = ::Stripe::Subscription.update(
|
|
295
314
|
processor_id,
|
|
296
315
|
{
|
|
@@ -303,9 +322,7 @@ module Pay
|
|
|
303
322
|
)
|
|
304
323
|
|
|
305
324
|
# Validate that swap was successful and handle SCA if needed
|
|
306
|
-
|
|
307
|
-
Pay::Payment.from_id(payment_intent_id, stripe_account: stripe_account).validate
|
|
308
|
-
end
|
|
325
|
+
validate_latest_payment
|
|
309
326
|
|
|
310
327
|
sync!(object: @api_record)
|
|
311
328
|
rescue ::Stripe::StripeError => e
|
|
@@ -369,6 +386,23 @@ module Pay
|
|
|
369
386
|
|
|
370
387
|
private
|
|
371
388
|
|
|
389
|
+
# Stripe sets the status to `paused` when a trial ends without a payment method
|
|
390
|
+
def status_paused?
|
|
391
|
+
status == "paused"
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Pausing collection with `void` leaves the status unchanged
|
|
395
|
+
def pause_behavior_void?
|
|
396
|
+
pause_behavior == "void"
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
# Raises Pay::InvalidPaymentMethod or Pay::ActionRequired if the latest invoice's payment is incomplete
|
|
400
|
+
def validate_latest_payment
|
|
401
|
+
if (payment_intent = latest_payment)
|
|
402
|
+
Pay::Payment.new(payment_intent, stripe_account: stripe_account).validate
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
372
406
|
# Options for Stripe requests
|
|
373
407
|
def stripe_options
|
|
374
408
|
{stripe_account: stripe_account}.compact
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
<% scope = @payment.setup_intent? ? "pay.setup_intent" : "pay" %>
|
|
1
2
|
<div
|
|
2
3
|
data-controller="payment-intent"
|
|
3
4
|
data-payment-intent-public-key-value="<%= Pay::Stripe.public_key %>"
|
|
4
5
|
data-payment-intent-stripe-account-value="<%= @payment.stripe_account %>"
|
|
5
6
|
data-payment-intent-client-secret-value="<%= @payment.client_secret %>"
|
|
6
7
|
data-payment-intent-status-value="<%= @payment.status %>"
|
|
8
|
+
data-payment-intent-setup-intent-value="<%= @payment.setup_intent? %>"
|
|
7
9
|
data-payment-intent-customer-value="<%= @payment.customer %>"
|
|
8
10
|
data-payment-intent-name-missing-message-value="<%= t("pay.requires_action.name_missing") %>"
|
|
9
|
-
data-payment-intent-confirmed-message-value="<%= t("
|
|
11
|
+
data-payment-intent-confirmed-message-value="<%= t("requires_action.success", scope: scope) %>"
|
|
10
12
|
class="h-screen md:flex md:justify-center md:items-center">
|
|
11
13
|
<div class="w-full max-w-lg">
|
|
12
14
|
<!-- Status Messages -->
|
|
@@ -28,18 +30,18 @@
|
|
|
28
30
|
|
|
29
31
|
<div class="bg-white rounded-lg shadow-xl p-4 sm:py-6 sm:px-10 mb-5">
|
|
30
32
|
<% if @payment.succeeded? %>
|
|
31
|
-
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "
|
|
32
|
-
<p class="mb-6"><%=t "
|
|
33
|
+
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "successful.header", scope: scope %></h1>
|
|
34
|
+
<p class="mb-6"><%=t "successful.description", scope: scope %></p>
|
|
33
35
|
|
|
34
36
|
<% elsif @payment.canceled? %>
|
|
35
|
-
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "
|
|
36
|
-
<p class="mb-6"><%=t "
|
|
37
|
+
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "cancelled.header", scope: scope %></h1>
|
|
38
|
+
<p class="mb-6"><%=t "cancelled.description", scope: scope %></p>
|
|
37
39
|
|
|
38
40
|
<% else %>
|
|
39
41
|
<div data-payment-intent-target="form" id="payment-elements">
|
|
40
42
|
<!-- Instructions -->
|
|
41
|
-
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "
|
|
42
|
-
<p class="mb-6"><%=t "
|
|
43
|
+
<h1 class="text-xl mt-2 mb-4 text-gray-700"><%=t "requires_action.header", scope: scope, amount: @payment.amount_with_currency %></h1>
|
|
44
|
+
<p class="mb-6"><%=t "requires_action.description", scope: scope %></p>
|
|
43
45
|
|
|
44
46
|
<div data-payment-intent-target="cardFields" class="hidden">
|
|
45
47
|
<!-- Name -->
|
|
@@ -53,7 +55,7 @@
|
|
|
53
55
|
|
|
54
56
|
<!-- Pay Button -->
|
|
55
57
|
<button data-payment-intent-target="button" data-action="click->payment-intent#confirmPayment" class="inline-block w-full px-4 py-3 mb-4 text-white rounded-lg bg-blue-400 hover:bg-blue-500">
|
|
56
|
-
<%=t "
|
|
58
|
+
<%=t "requires_action.button", scope: scope, amount: @payment.amount_with_currency %>
|
|
57
59
|
</button>
|
|
58
60
|
</div>
|
|
59
61
|
<% end %>
|
|
@@ -79,6 +81,7 @@
|
|
|
79
81
|
clientSecret: String,
|
|
80
82
|
customer: String,
|
|
81
83
|
status: String,
|
|
84
|
+
setupIntent: Boolean,
|
|
82
85
|
nameMissingMessage: String,
|
|
83
86
|
confirmedMessage: String,
|
|
84
87
|
errorMessage: String,
|
|
@@ -104,7 +107,7 @@
|
|
|
104
107
|
switch(this.statusValue) {
|
|
105
108
|
case "requires_action":
|
|
106
109
|
this.processingValue = true
|
|
107
|
-
this.
|
|
110
|
+
this.confirm({clientSecret: this.clientSecretValue})
|
|
108
111
|
break
|
|
109
112
|
case "requires_payment_method":
|
|
110
113
|
this.cardFieldsTarget.classList.toggle("hidden", false)
|
|
@@ -114,7 +117,14 @@
|
|
|
114
117
|
|
|
115
118
|
confirmPayment() {
|
|
116
119
|
this.processingValue = true
|
|
117
|
-
this.
|
|
120
|
+
this.confirm({elements: this.elements})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// SetupIntents (saving a payment method) and PaymentIntents confirm through different Stripe.js methods
|
|
124
|
+
confirm(options) {
|
|
125
|
+
const params = {...options, confirmParams: { return_url: document.location.href }}
|
|
126
|
+
const result = this.setupIntentValue ? this.stripe.confirmSetup(params) : this.stripe.confirmPayment(params)
|
|
127
|
+
result.then(this.handleConfirmResult.bind(this))
|
|
118
128
|
}
|
|
119
129
|
|
|
120
130
|
handleConfirmResult(result) {
|
|
@@ -126,7 +136,8 @@
|
|
|
126
136
|
this.errorMessageValue = this.nameMissingMessageValue
|
|
127
137
|
} else {
|
|
128
138
|
this.errorMessageValue = result.error.message
|
|
129
|
-
|
|
139
|
+
const intent = result.error.payment_intent || result.error.setup_intent
|
|
140
|
+
if (intent) { this.statusValue = intent.status }
|
|
130
141
|
}
|
|
131
142
|
} else {
|
|
132
143
|
this.completeValue = true
|
data/config/locales/en.yml
CHANGED
|
@@ -14,6 +14,18 @@ en:
|
|
|
14
14
|
button: "Pay %{amount}"
|
|
15
15
|
name_missing: "Please provide your name."
|
|
16
16
|
success: "The payment was successful."
|
|
17
|
+
setup_intent:
|
|
18
|
+
successful:
|
|
19
|
+
header: "Payment Method Saved"
|
|
20
|
+
description: "Your payment method was successfully confirmed."
|
|
21
|
+
cancelled:
|
|
22
|
+
header: "Setup Cancelled"
|
|
23
|
+
description: "This payment method setup was cancelled."
|
|
24
|
+
requires_action:
|
|
25
|
+
header: "Confirm your payment method"
|
|
26
|
+
description: "Extra confirmation is needed to save your payment method. Please confirm it by filling out your payment details below."
|
|
27
|
+
button: "Save payment method"
|
|
28
|
+
success: "Your payment method was saved."
|
|
17
29
|
all_rights_reserved: "All rights reserved."
|
|
18
30
|
back: "Go back"
|
|
19
31
|
refund: "Refund"
|
data/lib/pay/paddle_billing.rb
CHANGED
|
@@ -14,11 +14,13 @@ module Pay
|
|
|
14
14
|
|
|
15
15
|
extend Env
|
|
16
16
|
|
|
17
|
+
REQUIRED_VERSION = "~> 3"
|
|
18
|
+
|
|
17
19
|
def self.enabled?
|
|
18
20
|
return false unless Pay.enabled_processors.include?(:paddle_billing) && defined?(::Paddle)
|
|
19
21
|
|
|
20
|
-
Pay::Engine.version_matches?(required:
|
|
21
|
-
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version
|
|
22
|
+
Pay::Engine.version_matches?(required: REQUIRED_VERSION,
|
|
23
|
+
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version #{REQUIRED_VERSION}")
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def self.setup
|
data/lib/pay/paddle_classic.rb
CHANGED
|
@@ -18,11 +18,13 @@ module Pay
|
|
|
18
18
|
|
|
19
19
|
extend Env
|
|
20
20
|
|
|
21
|
+
REQUIRED_VERSION = "~> 3"
|
|
22
|
+
|
|
21
23
|
def self.enabled?
|
|
22
24
|
return false unless Pay.enabled_processors.include?(:paddle_classic) && defined?(::Paddle)
|
|
23
25
|
|
|
24
|
-
Pay::Engine.version_matches?(required:
|
|
25
|
-
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version
|
|
26
|
+
Pay::Engine.version_matches?(required: REQUIRED_VERSION,
|
|
27
|
+
current: ::Paddle::VERSION) || (raise "[Pay] paddle gem must be version #{REQUIRED_VERSION}")
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def self.client
|
data/lib/pay/payment.rb
CHANGED
|
@@ -19,6 +19,10 @@ module Pay
|
|
|
19
19
|
@stripe_account = stripe_account
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def setup_intent?
|
|
23
|
+
intent.is_a?(::Stripe::SetupIntent)
|
|
24
|
+
end
|
|
25
|
+
|
|
22
26
|
def requires_payment_method?
|
|
23
27
|
status == "requires_payment_method"
|
|
24
28
|
end
|
|
@@ -35,7 +39,9 @@ module Pay
|
|
|
35
39
|
status == "succeeded"
|
|
36
40
|
end
|
|
37
41
|
|
|
42
|
+
# SetupIntents save a payment method for later and have no amount
|
|
38
43
|
def amount_with_currency
|
|
44
|
+
return if setup_intent?
|
|
39
45
|
Pay::Currency.format(amount, currency: currency)
|
|
40
46
|
end
|
|
41
47
|
|
data/lib/pay/stripe.rb
CHANGED
data/lib/pay/version.rb
CHANGED
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: 12.
|
|
4
|
+
version: 12.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jason Charnes
|
|
@@ -191,7 +191,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
191
191
|
- !ruby/object:Gem::Version
|
|
192
192
|
version: '0'
|
|
193
193
|
requirements: []
|
|
194
|
-
rubygems_version: 4.0.
|
|
194
|
+
rubygems_version: 4.0.20
|
|
195
195
|
specification_version: 4
|
|
196
196
|
summary: Payments engine for Ruby on Rails
|
|
197
197
|
test_files: []
|