pay 2.7.0 → 3.0.1
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 +4 -4
- data/README.md +35 -696
- data/app/controllers/pay/webhooks/braintree_controller.rb +10 -3
- data/app/controllers/pay/webhooks/paddle_controller.rb +7 -8
- data/app/controllers/pay/webhooks/stripe_controller.rb +6 -3
- data/app/jobs/pay/{email_sync_job.rb → customer_sync_job.rb} +3 -4
- data/app/models/pay/application_record.rb +1 -5
- data/app/models/pay/charge.rb +31 -18
- data/app/models/pay/customer.rb +87 -0
- data/app/models/pay/merchant.rb +19 -0
- data/app/models/pay/payment_method.rb +41 -0
- data/app/models/pay/subscription.rb +42 -30
- data/app/models/pay/webhook.rb +36 -0
- data/app/views/layouts/pay/application.html.erb +2 -3
- data/app/views/pay/payments/show.html.erb +109 -81
- data/app/views/pay/user_mailer/receipt.html.erb +2 -2
- data/app/views/pay/user_mailer/refund.html.erb +2 -2
- data/config/locales/en.yml +1 -1
- data/db/migrate/1_create_pay_tables.rb +72 -0
- data/lib/generators/active_record/billable_generator.rb +44 -0
- data/lib/generators/active_record/merchant_generator.rb +44 -0
- data/lib/generators/active_record/templates/billable_migration.rb +17 -0
- data/lib/generators/active_record/templates/merchant_migration.rb +12 -0
- data/lib/generators/pay/{pay_generator.rb → billable_generator.rb} +2 -3
- data/lib/generators/pay/merchant_generator.rb +17 -0
- data/lib/generators/pay/orm_helpers.rb +10 -6
- data/lib/pay/adapter.rb +9 -0
- data/lib/pay/attributes.rb +74 -0
- data/lib/pay/billable/sync_customer.rb +30 -0
- data/lib/pay/braintree/billable.rb +133 -110
- data/lib/pay/braintree/payment_method.rb +42 -0
- data/lib/pay/braintree/subscription.rb +9 -12
- data/lib/pay/braintree/webhooks/subscription_canceled.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_charged_successfully.rb +4 -4
- data/lib/pay/braintree/webhooks/subscription_charged_unsuccessfully.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_expired.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_trial_ended.rb +2 -2
- data/lib/pay/braintree/webhooks/subscription_went_active.rb +1 -1
- data/lib/pay/braintree/webhooks/subscription_went_past_due.rb +1 -1
- data/lib/pay/braintree.rb +3 -2
- data/lib/pay/engine.rb +6 -1
- data/lib/pay/env.rb +8 -0
- data/lib/pay/fake_processor/billable.rb +45 -21
- data/lib/pay/fake_processor/payment_method.rb +21 -0
- data/lib/pay/fake_processor/subscription.rb +11 -8
- data/lib/pay/fake_processor.rb +2 -1
- data/lib/pay/nano_id.rb +13 -0
- data/lib/pay/paddle/billable.rb +18 -48
- data/lib/pay/paddle/charge.rb +5 -5
- data/lib/pay/paddle/payment_method.rb +60 -0
- data/lib/pay/paddle/response.rb +0 -0
- data/lib/pay/paddle/subscription.rb +49 -8
- data/lib/pay/paddle/webhooks/subscription_cancelled.rb +6 -3
- data/lib/pay/paddle/webhooks/subscription_created.rb +1 -40
- data/lib/pay/paddle/webhooks/subscription_payment_refunded.rb +3 -3
- data/lib/pay/paddle/webhooks/subscription_payment_succeeded.rb +26 -28
- data/lib/pay/paddle/webhooks/subscription_updated.rb +2 -2
- data/lib/pay/paddle.rb +7 -3
- data/lib/pay/payment.rb +1 -1
- data/lib/pay/receipts.rb +35 -7
- data/lib/pay/stripe/billable.rb +80 -102
- data/lib/pay/stripe/charge.rb +59 -3
- data/lib/pay/stripe/merchant.rb +10 -10
- data/lib/pay/stripe/payment_method.rb +61 -0
- data/lib/pay/stripe/subscription.rb +70 -8
- data/lib/pay/stripe/webhooks/account_updated.rb +2 -3
- data/lib/pay/stripe/webhooks/charge_refunded.rb +2 -7
- data/lib/pay/stripe/webhooks/charge_succeeded.rb +2 -8
- data/lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb +15 -0
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +15 -0
- data/lib/pay/stripe/webhooks/customer_deleted.rb +7 -15
- data/lib/pay/stripe/webhooks/customer_updated.rb +10 -3
- data/lib/pay/stripe/webhooks/payment_action_required.rb +2 -2
- data/lib/pay/stripe/webhooks/payment_intent_succeeded.rb +6 -14
- data/lib/pay/stripe/webhooks/payment_method_attached.rb +15 -0
- data/lib/pay/stripe/webhooks/payment_method_detached.rb +12 -0
- data/lib/pay/stripe/webhooks/payment_method_updated.rb +10 -4
- data/lib/pay/stripe/webhooks/subscription_created.rb +1 -36
- data/lib/pay/stripe/webhooks/subscription_deleted.rb +2 -9
- data/lib/pay/stripe/webhooks/subscription_renewing.rb +14 -6
- data/lib/pay/stripe/webhooks/subscription_updated.rb +1 -29
- data/lib/pay/stripe.rb +12 -3
- data/lib/pay/version.rb +1 -1
- data/lib/pay/webhooks/delegator.rb +4 -0
- data/lib/pay/webhooks/process_job.rb +9 -0
- data/lib/pay/webhooks.rb +1 -0
- data/lib/pay.rb +7 -78
- data/lib/tasks/pay.rake +20 -0
- metadata +31 -39
- data/app/models/pay.rb +0 -5
- data/db/migrate/20170205020145_create_pay_subscriptions.rb +0 -17
- data/db/migrate/20170727235816_create_pay_charges.rb +0 -18
- data/db/migrate/20190816015720_add_status_to_pay_subscriptions.rb +0 -14
- data/db/migrate/20200603134434_add_data_to_pay_models.rb +0 -15
- data/db/migrate/20210309004259_add_data_to_pay_billable.rb +0 -19
- data/db/migrate/20210406215234_add_currency_to_pay_charges.rb +0 -5
- data/db/migrate/20210406215506_add_application_fee_to_pay_models.rb +0 -7
- data/lib/generators/active_record/pay_generator.rb +0 -58
- data/lib/generators/active_record/templates/migration.rb +0 -9
- data/lib/pay/billable/sync_email.rb +0 -40
- data/lib/pay/billable.rb +0 -172
@@ -0,0 +1,42 @@
|
|
1
|
+
module Pay
|
2
|
+
module Braintree
|
3
|
+
class PaymentMethod
|
4
|
+
attr_reader :pay_payment_method
|
5
|
+
|
6
|
+
delegate :customer, :processor_id, to: :pay_payment_method
|
7
|
+
|
8
|
+
def self.sync(id, object: nil, try: 0, retries: 1)
|
9
|
+
object ||= gateway.payment_method.find(id)
|
10
|
+
|
11
|
+
pay_customer = Pay::Customer.find_by(processor: :braintree, processor_id: object.customer_id)
|
12
|
+
return unless pay_customer
|
13
|
+
|
14
|
+
pay_customer.save_payment_method(object, default: object.default?)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(pay_payment_method)
|
18
|
+
@pay_payment_method = pay_payment_method
|
19
|
+
end
|
20
|
+
|
21
|
+
# Sets payment method as default on Stripe
|
22
|
+
def make_default!
|
23
|
+
result = gateway.customer.update(customer.processor_id, default_payment_method_token: processor_id)
|
24
|
+
raise Pay::Braintree::Error, result unless result.success?
|
25
|
+
result.success?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Remove payment method
|
29
|
+
def detach
|
30
|
+
result = gateway.payment_method.delete(processor_id)
|
31
|
+
raise Pay::Braintree::Error, result unless result.success?
|
32
|
+
result.success?
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def gateway
|
38
|
+
Pay.braintree_gateway
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -4,11 +4,11 @@ module Pay
|
|
4
4
|
attr_reader :pay_subscription
|
5
5
|
|
6
6
|
delegate :active?,
|
7
|
+
:customer,
|
7
8
|
:canceled?,
|
8
9
|
:ends_at,
|
9
10
|
:name,
|
10
11
|
:on_trial?,
|
11
|
-
:owner,
|
12
12
|
:processor_id,
|
13
13
|
:processor_plan,
|
14
14
|
:processor_subscription,
|
@@ -45,13 +45,13 @@ module Pay
|
|
45
45
|
|
46
46
|
def cancel_now!
|
47
47
|
gateway.subscription.cancel(processor_subscription.id)
|
48
|
-
pay_subscription.update(status: :canceled, ends_at: Time.
|
48
|
+
pay_subscription.update(status: :canceled, ends_at: Time.current)
|
49
49
|
rescue ::Braintree::BraintreeError => e
|
50
50
|
raise Pay::Braintree::Error, e
|
51
51
|
end
|
52
52
|
|
53
53
|
def on_grace_period?
|
54
|
-
canceled? && Time.
|
54
|
+
canceled? && Time.current < ends_at
|
55
55
|
end
|
56
56
|
|
57
57
|
def paused?
|
@@ -70,7 +70,7 @@ module Pay
|
|
70
70
|
if canceled? && on_trial?
|
71
71
|
duration = trial_ends_at.to_date - Date.today
|
72
72
|
|
73
|
-
|
73
|
+
customer.subscribe(
|
74
74
|
name: name,
|
75
75
|
plan: processor_plan,
|
76
76
|
trial_period: true,
|
@@ -92,13 +92,15 @@ module Pay
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def swap(plan)
|
95
|
+
raise ArgumentError, "plan must be a string" unless plan.is_a?(String)
|
96
|
+
|
95
97
|
if on_grace_period? && processor_plan == plan
|
96
98
|
resume
|
97
99
|
return
|
98
100
|
end
|
99
101
|
|
100
102
|
unless active?
|
101
|
-
|
103
|
+
customer.subscribe(name: name, plan: plan, trial_period: false)
|
102
104
|
return
|
103
105
|
end
|
104
106
|
|
@@ -120,12 +122,7 @@ module Pay
|
|
120
122
|
prorate_charges: prorate?
|
121
123
|
}
|
122
124
|
})
|
123
|
-
|
124
|
-
if result.success?
|
125
|
-
pay_subscription.update(status: :active, processor_plan: braintree_plan.id, ends_at: nil)
|
126
|
-
else
|
127
|
-
raise Error, "Braintree failed to swap plans: #{result.message}"
|
128
|
-
end
|
125
|
+
raise Error, "Braintree failed to swap plans: #{result.message}" unless result.success?
|
129
126
|
rescue ::Braintree::BraintreeError => e
|
130
127
|
raise Pay::Braintree::Error, e
|
131
128
|
end
|
@@ -205,7 +202,7 @@ module Pay
|
|
205
202
|
|
206
203
|
cancel_now!
|
207
204
|
|
208
|
-
|
205
|
+
customer.subscribe(**options.merge(name: name, plan: plan.id))
|
209
206
|
end
|
210
207
|
end
|
211
208
|
end
|
@@ -8,7 +8,7 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
14
|
pay_subscription.update!(ends_at: Time.current, status: :canceled)
|
@@ -8,14 +8,14 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
|
-
|
15
|
-
charge = Pay::Braintree::Billable.new(
|
14
|
+
pay_customer = pay_subscription.customer
|
15
|
+
charge = Pay::Braintree::Billable.new(pay_customer).save_transaction(subscription.transactions.first)
|
16
16
|
|
17
17
|
if Pay.send_emails
|
18
|
-
Pay::UserMailer.with(billable:
|
18
|
+
Pay::UserMailer.with(billable: pay_customer.owner, charge: charge).receipt.deliver_later
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -8,7 +8,7 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
14
|
# billable = pay_subscription.owner
|
@@ -8,7 +8,7 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
14
|
pay_subscription.update!(ends_at: Time.current, status: :canceled)
|
@@ -8,10 +8,10 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
|
-
pay_subscription.update(trial_ends_at: Time.
|
14
|
+
pay_subscription.update(trial_ends_at: Time.current)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -8,7 +8,7 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
14
|
pay_subscription.update!(status: :active)
|
@@ -8,7 +8,7 @@ module Pay
|
|
8
8
|
subscription = event.subscription
|
9
9
|
return if subscription.nil?
|
10
10
|
|
11
|
-
pay_subscription = Pay.
|
11
|
+
pay_subscription = Pay::Subscription.find_by_processor_and_id(:braintree, subscription.id)
|
12
12
|
return unless pay_subscription.present?
|
13
13
|
|
14
14
|
pay_subscription.update!(status: :past_due)
|
data/lib/pay/braintree.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Pay
|
2
2
|
module Braintree
|
3
|
+
autoload :AuthorizationError, "pay/braintree/authorization_error"
|
3
4
|
autoload :Billable, "pay/braintree/billable"
|
4
5
|
autoload :Charge, "pay/braintree/charge"
|
5
|
-
autoload :Subscription, "pay/braintree/subscription"
|
6
6
|
autoload :Error, "pay/braintree/error"
|
7
|
-
autoload :
|
7
|
+
autoload :PaymentMethod, "pay/braintree/payment_method"
|
8
|
+
autoload :Subscription, "pay/braintree/subscription"
|
8
9
|
|
9
10
|
module Webhooks
|
10
11
|
autoload :SubscriptionCanceled, "pay/braintree/webhooks/subscription_canceled"
|
data/lib/pay/engine.rb
CHANGED
@@ -10,6 +10,11 @@ module Pay
|
|
10
10
|
mount Pay::Engine, at: Pay.routes_path, as: "pay"
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
# Include the pay attributes for ActiveRecord models
|
15
|
+
ActiveSupport.on_load(:active_record) do
|
16
|
+
include Pay::Attributes
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
config.to_prepare do
|
@@ -17,7 +22,7 @@ module Pay
|
|
17
22
|
Pay::Braintree.setup if defined? ::Braintree
|
18
23
|
Pay::Paddle.setup if defined? ::PaddlePay
|
19
24
|
|
20
|
-
Pay.
|
25
|
+
Pay::Charge.include Pay::Receipts if defined? ::Receipts::Receipt
|
21
26
|
end
|
22
27
|
end
|
23
28
|
end
|
data/lib/pay/env.rb
CHANGED
@@ -17,6 +17,14 @@ module Pay
|
|
17
17
|
secrets&.dig(env, scope, name) ||
|
18
18
|
credentials&.dig(scope, name) ||
|
19
19
|
secrets&.dig(scope, name)
|
20
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage
|
21
|
+
Rails.logger.error <<~MESSAGE
|
22
|
+
Rails was unable to decrypt credentials. Pay checks the Rails credentials to look for API keys for payment processors.
|
23
|
+
|
24
|
+
Make sure to set the `RAILS_MASTER_KEY` env variable or in the .key file. To learn more, run "bin/rails credentials:help"
|
25
|
+
|
26
|
+
If you're not using Rails credentials, you can delete `config/credentials.yml.enc` and `config/credentials/`.
|
27
|
+
MESSAGE
|
20
28
|
end
|
21
29
|
|
22
30
|
def env
|
@@ -1,46 +1,70 @@
|
|
1
1
|
module Pay
|
2
2
|
module FakeProcessor
|
3
3
|
class Billable
|
4
|
-
attr_reader :
|
4
|
+
attr_reader :pay_customer
|
5
5
|
|
6
6
|
delegate :processor_id,
|
7
7
|
:processor_id?,
|
8
8
|
:email,
|
9
9
|
:customer_name,
|
10
10
|
:card_token,
|
11
|
-
to: :
|
11
|
+
to: :pay_customer
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
@
|
13
|
+
def initialize(pay_customer)
|
14
|
+
@pay_customer = pay_customer
|
15
15
|
end
|
16
16
|
|
17
17
|
def customer
|
18
|
-
|
18
|
+
pay_customer.update!(processor_id: NanoId.generate) unless processor_id?
|
19
|
+
pay_customer
|
19
20
|
end
|
20
21
|
|
21
22
|
def charge(amount, options = {})
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
# Make to generate a processor_id
|
24
|
+
customer
|
25
|
+
|
26
|
+
attributes = options.merge(
|
27
|
+
processor_id: NanoId.generate,
|
25
28
|
amount: amount,
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
data: {
|
30
|
+
kind: :card,
|
31
|
+
type: :fake,
|
32
|
+
last4: 1234,
|
33
|
+
exp_month: Date.today.month,
|
34
|
+
exp_year: Date.today.year
|
35
|
+
}
|
30
36
|
)
|
37
|
+
pay_customer.charges.create!(attributes)
|
31
38
|
end
|
32
39
|
|
33
40
|
def subscribe(name: Pay.default_product_name, plan: Pay.default_plan_name, **options)
|
34
|
-
|
35
|
-
|
41
|
+
# Make to generate a processor_id
|
42
|
+
customer
|
43
|
+
|
44
|
+
attributes = options.merge(
|
45
|
+
processor_id: NanoId.generate,
|
46
|
+
name: name,
|
47
|
+
processor_plan: plan,
|
48
|
+
status: :active,
|
49
|
+
quantity: options.fetch(:quantity, 1)
|
50
|
+
)
|
51
|
+
pay_customer.subscriptions.create!(attributes)
|
36
52
|
end
|
37
53
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
54
|
+
def add_payment_method(payment_method_id, default: false)
|
55
|
+
# Make to generate a processor_id
|
56
|
+
customer
|
57
|
+
|
58
|
+
pay_customer.payment_methods.create!(
|
59
|
+
processor_id: NanoId.generate,
|
60
|
+
default: default,
|
61
|
+
type: :fake,
|
62
|
+
data: {
|
63
|
+
brand: "Fake",
|
64
|
+
last4: 1234,
|
65
|
+
exp_month: Date.today.month,
|
66
|
+
exp_year: Date.today.year
|
67
|
+
}
|
44
68
|
)
|
45
69
|
end
|
46
70
|
|
@@ -49,7 +73,7 @@ module Pay
|
|
49
73
|
end
|
50
74
|
|
51
75
|
def processor_subscription(subscription_id, options = {})
|
52
|
-
|
76
|
+
pay_customer.subscriptions.find_by(processor_id: subscription_id)
|
53
77
|
end
|
54
78
|
|
55
79
|
def trial_end_date(subscription)
|
@@ -0,0 +1,21 @@
|
|
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
|
@@ -23,8 +23,14 @@ module Pay
|
|
23
23
|
pay_subscription
|
24
24
|
end
|
25
25
|
|
26
|
+
# With trial, sets end to trial end (mimicing Stripe)
|
27
|
+
# Without trial, sets can ends_at to end of month
|
26
28
|
def cancel
|
27
|
-
pay_subscription.
|
29
|
+
if pay_subscription.on_trial?
|
30
|
+
pay_subscription.update(ends_at: pay_subscription.trial_ends_at)
|
31
|
+
else
|
32
|
+
pay_subscription.update(ends_at: Time.current.end_of_month)
|
33
|
+
end
|
28
34
|
end
|
29
35
|
|
30
36
|
def cancel_now!
|
@@ -32,27 +38,24 @@ module Pay
|
|
32
38
|
end
|
33
39
|
|
34
40
|
def on_grace_period?
|
35
|
-
canceled? && Time.
|
41
|
+
canceled? && Time.current < ends_at
|
36
42
|
end
|
37
43
|
|
38
44
|
def paused?
|
39
|
-
|
45
|
+
pay_subscription.status == "paused"
|
40
46
|
end
|
41
47
|
|
42
48
|
def pause
|
43
|
-
|
49
|
+
pay_subscription.update(status: :paused, trial_ends_at: Time.current)
|
44
50
|
end
|
45
51
|
|
46
52
|
def resume
|
47
|
-
unless on_grace_period?
|
53
|
+
unless on_grace_period? || paused?
|
48
54
|
raise StandardError, "You can only resume subscriptions within their grace period."
|
49
55
|
end
|
50
|
-
|
51
|
-
pay_subscription.update(ends_at: nil, status: :active)
|
52
56
|
end
|
53
57
|
|
54
58
|
def swap(plan)
|
55
|
-
pay_subscription.update(processor_plan: plan)
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
data/lib/pay/fake_processor.rb
CHANGED
@@ -2,7 +2,8 @@ module Pay
|
|
2
2
|
module FakeProcessor
|
3
3
|
autoload :Billable, "pay/fake_processor/billable"
|
4
4
|
autoload :Charge, "pay/fake_processor/charge"
|
5
|
-
autoload :Subscription, "pay/fake_processor/subscription"
|
6
5
|
autoload :Error, "pay/fake_processor/error"
|
6
|
+
autoload :PaymentMethod, "pay/fake_processor/payment_method"
|
7
|
+
autoload :Subscription, "pay/fake_processor/subscription"
|
7
8
|
end
|
8
9
|
end
|
data/lib/pay/nano_id.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module Pay
|
2
|
+
module NanoId
|
3
|
+
# Generates unique IDs - faster than UUID
|
4
|
+
ALPHABET = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".freeze
|
5
|
+
ALPHABET_SIZE = ALPHABET.size
|
6
|
+
|
7
|
+
def self.generate(size: 21)
|
8
|
+
id = ""
|
9
|
+
size.times { id << ALPHABET[(Random.rand * ALPHABET_SIZE).floor] }
|
10
|
+
id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|