pay 7.2.1 → 8.0.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 +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
|