pay 7.2.1 → 8.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/app/controllers/pay/webhooks/lemon_squeezy_controller.rb +45 -0
- data/app/controllers/pay/webhooks/stripe_controller.rb +2 -1
- data/app/jobs/pay/customer_sync_job.rb +1 -1
- data/app/models/concerns/pay/routing.rb +13 -0
- data/{lib → app/models}/pay/braintree/charge.rb +5 -12
- data/{lib/pay/braintree/billable.rb → app/models/pay/braintree/customer.rb} +31 -71
- data/{lib → app/models}/pay/braintree/payment_method.rb +1 -9
- data/{lib → app/models}/pay/braintree/subscription.rb +14 -52
- data/app/models/pay/charge.rb +8 -27
- data/app/models/pay/customer.rb +2 -15
- data/app/models/pay/fake_processor/charge.rb +13 -0
- data/{lib/pay/fake_processor/billable.rb → app/models/pay/fake_processor/customer.rb} +22 -35
- data/{lib → app/models}/pay/fake_processor/merchant.rb +2 -9
- data/app/models/pay/fake_processor/payment_method.rb +11 -0
- data/app/models/pay/fake_processor/subscription.rb +60 -0
- data/app/models/pay/lemon_squeezy/charge.rb +86 -0
- data/app/models/pay/lemon_squeezy/customer.rb +78 -0
- data/app/models/pay/lemon_squeezy/payment_method.rb +27 -0
- data/app/models/pay/lemon_squeezy/subscription.rb +129 -0
- data/app/models/pay/merchant.rb +0 -11
- data/{lib → app/models}/pay/paddle_billing/charge.rb +2 -8
- data/{lib/pay/paddle_billing/billable.rb → app/models/pay/paddle_billing/customer.rb} +18 -35
- data/{lib → app/models}/pay/paddle_billing/payment_method.rb +2 -12
- data/{lib → app/models}/pay/paddle_billing/subscription.rb +9 -33
- data/{lib → app/models}/pay/paddle_classic/charge.rb +13 -18
- data/{lib/pay/paddle_classic/billable.rb → app/models/pay/paddle_classic/customer.rb} +9 -31
- data/{lib → app/models}/pay/paddle_classic/payment_method.rb +1 -11
- data/{lib → app/models}/pay/paddle_classic/subscription.rb +11 -36
- data/app/models/pay/payment_method.rb +0 -5
- data/{lib → app/models}/pay/stripe/charge.rb +6 -22
- data/{lib/pay/stripe/billable.rb → app/models/pay/stripe/customer.rb} +73 -108
- data/{lib → app/models}/pay/stripe/merchant.rb +2 -11
- data/{lib → app/models}/pay/stripe/payment_method.rb +2 -10
- data/{lib → app/models}/pay/stripe/subscription.rb +37 -71
- data/app/models/pay/subscription.rb +7 -37
- data/app/models/pay/webhook.rb +2 -0
- data/config/routes.rb +1 -0
- data/db/migrate/2_add_pay_sti_columns.rb +24 -0
- data/lib/pay/attributes.rb +11 -3
- data/lib/pay/braintree.rb +25 -6
- data/lib/pay/engine.rb +2 -0
- data/lib/pay/fake_processor.rb +2 -6
- data/lib/pay/lemon_squeezy/webhooks/order.rb +11 -0
- data/lib/pay/lemon_squeezy/webhooks/subscription.rb +3 -3
- data/lib/pay/lemon_squeezy/webhooks/subscription_payment.rb +11 -0
- data/lib/pay/lemon_squeezy.rb +56 -104
- data/lib/pay/paddle_billing.rb +15 -6
- data/lib/pay/paddle_classic.rb +11 -9
- data/lib/pay/receipts.rb +6 -6
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +1 -1
- data/lib/pay/stripe/webhooks/customer_updated.rb +1 -1
- data/lib/pay/stripe/webhooks/subscription_trial_will_end.rb +1 -1
- data/lib/pay/stripe.rb +21 -7
- data/lib/pay/version.rb +1 -1
- data/lib/pay.rb +12 -1
- metadata +34 -38
- data/app/views/pay/stripe/_checkout_button.html.erb +0 -21
- data/lib/pay/braintree/authorization_error.rb +0 -9
- data/lib/pay/braintree/error.rb +0 -23
- data/lib/pay/fake_processor/charge.rb +0 -21
- data/lib/pay/fake_processor/error.rb +0 -6
- data/lib/pay/fake_processor/payment_method.rb +0 -21
- data/lib/pay/fake_processor/subscription.rb +0 -90
- data/lib/pay/lemon_squeezy/billable.rb +0 -90
- data/lib/pay/lemon_squeezy/charge.rb +0 -68
- data/lib/pay/lemon_squeezy/error.rb +0 -7
- data/lib/pay/lemon_squeezy/payment_method.rb +0 -40
- data/lib/pay/lemon_squeezy/subscription.rb +0 -185
- data/lib/pay/lemon_squeezy/webhooks/transaction_completed.rb +0 -11
- data/lib/pay/paddle_billing/error.rb +0 -7
- data/lib/pay/paddle_classic/error.rb +0 -7
- data/lib/pay/stripe/error.rb +0 -7
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:
|
4
|
+
version: 8.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Charnes
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-
|
13
|
+
date: 2024-09-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- app/controllers/pay/application_controller.rb
|
45
45
|
- app/controllers/pay/payments_controller.rb
|
46
46
|
- app/controllers/pay/webhooks/braintree_controller.rb
|
47
|
+
- app/controllers/pay/webhooks/lemon_squeezy_controller.rb
|
47
48
|
- app/controllers/pay/webhooks/paddle_billing_controller.rb
|
48
49
|
- app/controllers/pay/webhooks/paddle_classic_controller.rb
|
49
50
|
- app/controllers/pay/webhooks/stripe_controller.rb
|
@@ -52,16 +53,42 @@ files:
|
|
52
53
|
- app/jobs/pay/customer_sync_job.rb
|
53
54
|
- app/mailers/pay/application_mailer.rb
|
54
55
|
- app/mailers/pay/user_mailer.rb
|
56
|
+
- app/models/concerns/pay/routing.rb
|
55
57
|
- app/models/pay/application_record.rb
|
58
|
+
- app/models/pay/braintree/charge.rb
|
59
|
+
- app/models/pay/braintree/customer.rb
|
60
|
+
- app/models/pay/braintree/payment_method.rb
|
61
|
+
- app/models/pay/braintree/subscription.rb
|
56
62
|
- app/models/pay/charge.rb
|
57
63
|
- app/models/pay/customer.rb
|
64
|
+
- app/models/pay/fake_processor/charge.rb
|
65
|
+
- app/models/pay/fake_processor/customer.rb
|
66
|
+
- app/models/pay/fake_processor/merchant.rb
|
67
|
+
- app/models/pay/fake_processor/payment_method.rb
|
68
|
+
- app/models/pay/fake_processor/subscription.rb
|
69
|
+
- app/models/pay/lemon_squeezy/charge.rb
|
70
|
+
- app/models/pay/lemon_squeezy/customer.rb
|
71
|
+
- app/models/pay/lemon_squeezy/payment_method.rb
|
72
|
+
- app/models/pay/lemon_squeezy/subscription.rb
|
58
73
|
- app/models/pay/merchant.rb
|
74
|
+
- app/models/pay/paddle_billing/charge.rb
|
75
|
+
- app/models/pay/paddle_billing/customer.rb
|
76
|
+
- app/models/pay/paddle_billing/payment_method.rb
|
77
|
+
- app/models/pay/paddle_billing/subscription.rb
|
78
|
+
- app/models/pay/paddle_classic/charge.rb
|
79
|
+
- app/models/pay/paddle_classic/customer.rb
|
80
|
+
- app/models/pay/paddle_classic/payment_method.rb
|
81
|
+
- app/models/pay/paddle_classic/subscription.rb
|
59
82
|
- app/models/pay/payment_method.rb
|
83
|
+
- app/models/pay/stripe/charge.rb
|
84
|
+
- app/models/pay/stripe/customer.rb
|
85
|
+
- app/models/pay/stripe/merchant.rb
|
86
|
+
- app/models/pay/stripe/payment_method.rb
|
87
|
+
- app/models/pay/stripe/subscription.rb
|
60
88
|
- app/models/pay/subscription.rb
|
61
89
|
- app/models/pay/webhook.rb
|
62
90
|
- app/views/layouts/pay/application.html.erb
|
63
91
|
- app/views/pay/payments/show.html.erb
|
64
|
-
- app/views/pay/stripe/_checkout_button.html.erb
|
65
92
|
- app/views/pay/user_mailer/payment_action_required.html.erb
|
66
93
|
- app/views/pay/user_mailer/payment_failed.html.erb
|
67
94
|
- app/views/pay/user_mailer/receipt.html.erb
|
@@ -73,6 +100,7 @@ files:
|
|
73
100
|
- config/locales/en.yml
|
74
101
|
- config/routes.rb
|
75
102
|
- db/migrate/1_create_pay_tables.rb
|
103
|
+
- db/migrate/2_add_pay_sti_columns.rb
|
76
104
|
- lib/generators/pay/email_views_generator.rb
|
77
105
|
- lib/generators/pay/views_generator.rb
|
78
106
|
- lib/pay.rb
|
@@ -80,12 +108,6 @@ files:
|
|
80
108
|
- lib/pay/attributes.rb
|
81
109
|
- lib/pay/billable/sync_customer.rb
|
82
110
|
- lib/pay/braintree.rb
|
83
|
-
- lib/pay/braintree/authorization_error.rb
|
84
|
-
- lib/pay/braintree/billable.rb
|
85
|
-
- lib/pay/braintree/charge.rb
|
86
|
-
- lib/pay/braintree/error.rb
|
87
|
-
- lib/pay/braintree/payment_method.rb
|
88
|
-
- lib/pay/braintree/subscription.rb
|
89
111
|
- lib/pay/braintree/webhooks/subscription_canceled.rb
|
90
112
|
- lib/pay/braintree/webhooks/subscription_charged_successfully.rb
|
91
113
|
- lib/pay/braintree/webhooks/subscription_charged_unsuccessfully.rb
|
@@ -98,35 +120,15 @@ files:
|
|
98
120
|
- lib/pay/env.rb
|
99
121
|
- lib/pay/errors.rb
|
100
122
|
- lib/pay/fake_processor.rb
|
101
|
-
- lib/pay/fake_processor/billable.rb
|
102
|
-
- lib/pay/fake_processor/charge.rb
|
103
|
-
- lib/pay/fake_processor/error.rb
|
104
|
-
- lib/pay/fake_processor/merchant.rb
|
105
|
-
- lib/pay/fake_processor/payment_method.rb
|
106
|
-
- lib/pay/fake_processor/subscription.rb
|
107
123
|
- lib/pay/lemon_squeezy.rb
|
108
|
-
- lib/pay/lemon_squeezy/
|
109
|
-
- lib/pay/lemon_squeezy/charge.rb
|
110
|
-
- lib/pay/lemon_squeezy/error.rb
|
111
|
-
- lib/pay/lemon_squeezy/payment_method.rb
|
112
|
-
- lib/pay/lemon_squeezy/subscription.rb
|
124
|
+
- lib/pay/lemon_squeezy/webhooks/order.rb
|
113
125
|
- lib/pay/lemon_squeezy/webhooks/subscription.rb
|
114
|
-
- lib/pay/lemon_squeezy/webhooks/
|
126
|
+
- lib/pay/lemon_squeezy/webhooks/subscription_payment.rb
|
115
127
|
- lib/pay/nano_id.rb
|
116
128
|
- lib/pay/paddle_billing.rb
|
117
|
-
- lib/pay/paddle_billing/billable.rb
|
118
|
-
- lib/pay/paddle_billing/charge.rb
|
119
|
-
- lib/pay/paddle_billing/error.rb
|
120
|
-
- lib/pay/paddle_billing/payment_method.rb
|
121
|
-
- lib/pay/paddle_billing/subscription.rb
|
122
129
|
- lib/pay/paddle_billing/webhooks/subscription.rb
|
123
130
|
- lib/pay/paddle_billing/webhooks/transaction_completed.rb
|
124
131
|
- lib/pay/paddle_classic.rb
|
125
|
-
- lib/pay/paddle_classic/billable.rb
|
126
|
-
- lib/pay/paddle_classic/charge.rb
|
127
|
-
- lib/pay/paddle_classic/error.rb
|
128
|
-
- lib/pay/paddle_classic/payment_method.rb
|
129
|
-
- lib/pay/paddle_classic/subscription.rb
|
130
132
|
- lib/pay/paddle_classic/webhooks/signature_verifier.rb
|
131
133
|
- lib/pay/paddle_classic/webhooks/subscription_cancelled.rb
|
132
134
|
- lib/pay/paddle_classic/webhooks/subscription_created.rb
|
@@ -136,12 +138,6 @@ files:
|
|
136
138
|
- lib/pay/payment.rb
|
137
139
|
- lib/pay/receipts.rb
|
138
140
|
- lib/pay/stripe.rb
|
139
|
-
- lib/pay/stripe/billable.rb
|
140
|
-
- lib/pay/stripe/charge.rb
|
141
|
-
- lib/pay/stripe/error.rb
|
142
|
-
- lib/pay/stripe/merchant.rb
|
143
|
-
- lib/pay/stripe/payment_method.rb
|
144
|
-
- lib/pay/stripe/subscription.rb
|
145
141
|
- lib/pay/stripe/webhooks/account_updated.rb
|
146
142
|
- lib/pay/stripe/webhooks/charge_refunded.rb
|
147
143
|
- lib/pay/stripe/webhooks/charge_succeeded.rb
|
@@ -184,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
180
|
- !ruby/object:Gem::Version
|
185
181
|
version: '0'
|
186
182
|
requirements: []
|
187
|
-
rubygems_version: 3.
|
183
|
+
rubygems_version: 3.5.16
|
188
184
|
signing_key:
|
189
185
|
specification_version: 4
|
190
186
|
summary: Payments engine for Ruby on Rails
|
@@ -1,21 +0,0 @@
|
|
1
|
-
<%= button_tag title,
|
2
|
-
id: "checkout-#{session.id}",
|
3
|
-
class: local_assigns[:class],
|
4
|
-
style: (local_assigns[:class] || local_assigns[:style]) ? local_assigns[:style] : 'background-color:#6772E5;color:#FFF;padding:8px 12px;border:0;border-radius:4px;font-size:1em'
|
5
|
-
%>
|
6
|
-
<%= tag.div id: "error-for-#{session.id}" %>
|
7
|
-
|
8
|
-
<script>
|
9
|
-
(() => {
|
10
|
-
const checkoutButton = document.getElementById("checkout-<%= session.id %>");
|
11
|
-
checkoutButton.addEventListener('click', function () {
|
12
|
-
Stripe("<%= Pay::Stripe.public_key %>").redirectToCheckout({
|
13
|
-
sessionId: '<%= session.id %>'
|
14
|
-
}).then(function (result) {
|
15
|
-
if (result.error) {
|
16
|
-
document.getElementById("error-for-#{session.id}").innerText = result.error.message;
|
17
|
-
}
|
18
|
-
});
|
19
|
-
});
|
20
|
-
})()
|
21
|
-
</script>
|
data/lib/pay/braintree/error.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module Braintree
|
3
|
-
class Error < Pay::Error
|
4
|
-
# For any manually raised Braintree error results (for failure responses)
|
5
|
-
# we can raise this exception manually but treat it as if we wrapped an exception
|
6
|
-
|
7
|
-
attr_reader :result
|
8
|
-
|
9
|
-
def initialize(result)
|
10
|
-
if result.is_a?(::Braintree::ErrorResult)
|
11
|
-
super(result.message)
|
12
|
-
@result = result
|
13
|
-
else
|
14
|
-
super
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def cause
|
19
|
-
super || result
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module FakeProcessor
|
3
|
-
class Charge
|
4
|
-
attr_reader :pay_charge
|
5
|
-
|
6
|
-
delegate :processor_id, :owner, to: :pay_charge
|
7
|
-
|
8
|
-
def initialize(pay_charge)
|
9
|
-
@pay_charge = pay_charge
|
10
|
-
end
|
11
|
-
|
12
|
-
def charge
|
13
|
-
pay_charge
|
14
|
-
end
|
15
|
-
|
16
|
-
def refund!(amount_to_refund)
|
17
|
-
pay_charge.update(amount_refunded: amount_to_refund)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module FakeProcessor
|
3
|
-
class PaymentMethod
|
4
|
-
attr_reader :pay_payment_method
|
5
|
-
|
6
|
-
delegate :customer, :processor_id, to: :pay_payment_method
|
7
|
-
|
8
|
-
def initialize(pay_payment_method)
|
9
|
-
@pay_payment_method = pay_payment_method
|
10
|
-
end
|
11
|
-
|
12
|
-
# Sets payment method as default on Stripe
|
13
|
-
def make_default!
|
14
|
-
end
|
15
|
-
|
16
|
-
# Remove payment method
|
17
|
-
def detach
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module FakeProcessor
|
3
|
-
class Subscription
|
4
|
-
attr_reader :pay_subscription
|
5
|
-
|
6
|
-
delegate :active?,
|
7
|
-
:canceled?,
|
8
|
-
:on_grace_period?,
|
9
|
-
:on_trial?,
|
10
|
-
:ends_at,
|
11
|
-
:ends_at?,
|
12
|
-
:owner,
|
13
|
-
:processor_subscription,
|
14
|
-
:processor_id,
|
15
|
-
:prorate,
|
16
|
-
:processor_plan,
|
17
|
-
:quantity?,
|
18
|
-
:quantity,
|
19
|
-
to: :pay_subscription
|
20
|
-
|
21
|
-
def initialize(pay_subscription)
|
22
|
-
@pay_subscription = pay_subscription
|
23
|
-
end
|
24
|
-
|
25
|
-
def subscription(**options)
|
26
|
-
pay_subscription
|
27
|
-
end
|
28
|
-
|
29
|
-
# With trial, sets end to trial end (mimicing Stripe)
|
30
|
-
# Without trial, sets can ends_at to end of month
|
31
|
-
def cancel(**options)
|
32
|
-
return if canceled?
|
33
|
-
|
34
|
-
if pay_subscription.on_trial?
|
35
|
-
pay_subscription.update(ends_at: pay_subscription.trial_ends_at)
|
36
|
-
else
|
37
|
-
pay_subscription.update(ends_at: Time.current.end_of_month)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def cancel_now!(**options)
|
42
|
-
return if canceled?
|
43
|
-
|
44
|
-
ends_at = Time.current
|
45
|
-
pay_subscription.update(
|
46
|
-
status: :canceled,
|
47
|
-
trial_ends_at: (ends_at if pay_subscription.trial_ends_at?),
|
48
|
-
ends_at: ends_at
|
49
|
-
)
|
50
|
-
end
|
51
|
-
|
52
|
-
def change_quantity(quantity, **options)
|
53
|
-
pay_subscription.update(quantity: quantity)
|
54
|
-
end
|
55
|
-
|
56
|
-
def on_grace_period?
|
57
|
-
ends_at? && ends_at > Time.current
|
58
|
-
end
|
59
|
-
|
60
|
-
def paused?
|
61
|
-
pay_subscription.status == "paused"
|
62
|
-
end
|
63
|
-
|
64
|
-
def pause
|
65
|
-
pay_subscription.update(status: :paused, trial_ends_at: Time.current)
|
66
|
-
end
|
67
|
-
|
68
|
-
def resumable?
|
69
|
-
on_grace_period? || paused?
|
70
|
-
end
|
71
|
-
|
72
|
-
def resume
|
73
|
-
unless resumable?
|
74
|
-
raise StandardError, "You can only resume subscriptions within their grace period."
|
75
|
-
end
|
76
|
-
|
77
|
-
pay_subscription.update(status: :active, trial_ends_at: nil, ends_at: nil)
|
78
|
-
end
|
79
|
-
|
80
|
-
def swap(plan, **options)
|
81
|
-
pay_subscription.update(processor_plan: plan, ends_at: nil, status: :active)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Retries the latest invoice for a Past Due subscription
|
85
|
-
def retry_failed_payment
|
86
|
-
pay_subscription.update(status: :active)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module PaddleBilling
|
3
|
-
class Billable
|
4
|
-
attr_reader :pay_customer
|
5
|
-
|
6
|
-
delegate :processor_id,
|
7
|
-
:processor_id?,
|
8
|
-
:email,
|
9
|
-
:customer_name,
|
10
|
-
:card_token,
|
11
|
-
to: :pay_customer
|
12
|
-
|
13
|
-
def initialize(pay_customer)
|
14
|
-
@pay_customer = pay_customer
|
15
|
-
end
|
16
|
-
|
17
|
-
def customer_attributes
|
18
|
-
{email: email, name: customer_name}
|
19
|
-
end
|
20
|
-
|
21
|
-
# Retrieves a Paddle::Customer object
|
22
|
-
#
|
23
|
-
# Finds an existing Paddle::Customer if processor_id exists
|
24
|
-
# Creates a new Paddle::Customer using `email` and `customer_name` if empty processor_id
|
25
|
-
#
|
26
|
-
# Returns a Paddle::Customer object
|
27
|
-
def customer
|
28
|
-
if processor_id?
|
29
|
-
::Paddle::Customer.retrieve(id: processor_id)
|
30
|
-
else
|
31
|
-
sc = ::Paddle::Customer.create(email: email, name: customer_name)
|
32
|
-
pay_customer.update!(processor_id: sc.id)
|
33
|
-
sc
|
34
|
-
end
|
35
|
-
rescue ::Paddle::Error => e
|
36
|
-
raise Pay::PaddleBilling::Error, e
|
37
|
-
end
|
38
|
-
|
39
|
-
# Syncs name and email to Paddle::Customer
|
40
|
-
# You can also pass in other attributes that will be merged into the default attributes
|
41
|
-
def update_customer!(**attributes)
|
42
|
-
customer unless processor_id?
|
43
|
-
attrs = customer_attributes.merge(attributes)
|
44
|
-
::Paddle::Customer.update(id: processor_id, **attrs)
|
45
|
-
end
|
46
|
-
|
47
|
-
def charge(amount, options = {})
|
48
|
-
return Pay::Error unless options
|
49
|
-
|
50
|
-
items = options[:items]
|
51
|
-
opts = options.except(:items).merge(customer_id: processor_id)
|
52
|
-
transaction = ::Paddle::Transaction.create(items: items, **opts)
|
53
|
-
|
54
|
-
attrs = {
|
55
|
-
amount: transaction.details.totals.grand_total,
|
56
|
-
created_at: transaction.created_at,
|
57
|
-
currency: transaction.currency_code,
|
58
|
-
metadata: transaction.details.line_items&.first&.id
|
59
|
-
}
|
60
|
-
|
61
|
-
charge = pay_customer.charges.find_or_initialize_by(processor_id: transaction.id)
|
62
|
-
charge.update(attrs)
|
63
|
-
charge
|
64
|
-
rescue ::Paddle::Error => e
|
65
|
-
raise Pay::PaddleBilling::Error, e
|
66
|
-
end
|
67
|
-
|
68
|
-
def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
|
69
|
-
# pass
|
70
|
-
end
|
71
|
-
|
72
|
-
# Paddle does not use payment method tokens. The method signature has it here
|
73
|
-
# to have a uniform API with the other payment processors.
|
74
|
-
def add_payment_method(token = nil, default: true)
|
75
|
-
Pay::PaddleBilling::PaymentMethod.sync(pay_customer: pay_customer)
|
76
|
-
end
|
77
|
-
|
78
|
-
def trial_end_date(subscription)
|
79
|
-
return unless subscription.state == "trialing"
|
80
|
-
Time.zone.parse(subscription.next_payment[:date]).end_of_day
|
81
|
-
end
|
82
|
-
|
83
|
-
def processor_subscription(subscription_id, options = {})
|
84
|
-
::Paddle::Subscription.retrieve(id: subscription_id, **options)
|
85
|
-
rescue ::Paddle::Error => e
|
86
|
-
raise Pay::PaddleBilling::Error, e
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module PaddleBilling
|
3
|
-
class Charge
|
4
|
-
attr_reader :pay_charge
|
5
|
-
|
6
|
-
delegate :processor_id, :customer, to: :pay_charge
|
7
|
-
|
8
|
-
def initialize(pay_charge)
|
9
|
-
@pay_charge = pay_charge
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.sync(charge_id, object: nil, try: 0, retries: 1)
|
13
|
-
# Skip loading the latest charge details from the API if we already have it
|
14
|
-
object ||= ::Paddle::Transaction.retrieve(id: charge_id)
|
15
|
-
|
16
|
-
# Ignore transactions that aren't completed
|
17
|
-
return unless object.status == "completed"
|
18
|
-
|
19
|
-
# Ignore charges without a Customer
|
20
|
-
return if object.customer_id.blank?
|
21
|
-
|
22
|
-
pay_customer = Pay::Customer.find_by(processor: :paddle_billing, processor_id: object.customer_id)
|
23
|
-
return unless pay_customer
|
24
|
-
|
25
|
-
# Ignore transactions that are payment method changes
|
26
|
-
# But update the customer's payment method
|
27
|
-
if object.origin == "subscription_payment_method_change"
|
28
|
-
Pay::PaddleBilling::PaymentMethod.sync(pay_customer: pay_customer, attributes: object.payments.first)
|
29
|
-
return
|
30
|
-
end
|
31
|
-
|
32
|
-
attrs = {
|
33
|
-
amount: object.details.totals.grand_total,
|
34
|
-
created_at: object.created_at,
|
35
|
-
currency: object.currency_code,
|
36
|
-
metadata: object.details.line_items&.first&.id,
|
37
|
-
subscription: pay_customer.subscriptions.find_by(processor_id: object.subscription_id)
|
38
|
-
}
|
39
|
-
|
40
|
-
if object.payment
|
41
|
-
case object.payment.method_details.type.downcase
|
42
|
-
when "card"
|
43
|
-
attrs[:payment_method_type] = "card"
|
44
|
-
attrs[:brand] = details.card.type
|
45
|
-
attrs[:exp_month] = details.card.expiry_month
|
46
|
-
attrs[:exp_year] = details.card.expiry_year
|
47
|
-
attrs[:last4] = details.card.last4
|
48
|
-
when "paypal"
|
49
|
-
attrs[:payment_method_type] = "paypal"
|
50
|
-
end
|
51
|
-
|
52
|
-
# Update customer's payment method
|
53
|
-
Pay::PaddleBilling::PaymentMethod.sync(pay_customer: pay_customer, attributes: object.payments.first)
|
54
|
-
end
|
55
|
-
|
56
|
-
# Update or create the charge
|
57
|
-
if (pay_charge = pay_customer.charges.find_by(processor_id: object.id))
|
58
|
-
pay_charge.with_lock do
|
59
|
-
pay_charge.update!(attrs)
|
60
|
-
end
|
61
|
-
pay_charge
|
62
|
-
else
|
63
|
-
pay_customer.charges.create!(attrs.merge(processor_id: object.id))
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module Pay
|
2
|
-
module PaddleBilling
|
3
|
-
class PaymentMethod
|
4
|
-
attr_reader :pay_payment_method
|
5
|
-
|
6
|
-
delegate :customer, :processor_id, to: :pay_payment_method
|
7
|
-
|
8
|
-
def self.sync(pay_customer:, attributes:)
|
9
|
-
details = attributes.method_details
|
10
|
-
attrs = {
|
11
|
-
type: details.type.downcase
|
12
|
-
}
|
13
|
-
|
14
|
-
case details.type.downcase
|
15
|
-
when "card"
|
16
|
-
attrs[:brand] = details.card.type
|
17
|
-
attrs[:last4] = details.card.last4
|
18
|
-
attrs[:exp_month] = details.card.expiry_month
|
19
|
-
attrs[:exp_year] = details.card.expiry_year
|
20
|
-
end
|
21
|
-
|
22
|
-
payment_method = pay_customer.payment_methods.find_or_initialize_by(processor_id: attributes.stored_payment_method_id)
|
23
|
-
payment_method.update!(attrs)
|
24
|
-
payment_method
|
25
|
-
end
|
26
|
-
|
27
|
-
def initialize(pay_payment_method)
|
28
|
-
@pay_payment_method = pay_payment_method
|
29
|
-
end
|
30
|
-
|
31
|
-
# Sets payment method as default
|
32
|
-
def make_default!
|
33
|
-
end
|
34
|
-
|
35
|
-
# Remove payment method
|
36
|
-
def detach
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|