pay 2.7.0 → 2.7.2
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 +93 -57
- data/app/models/pay/application_record.rb +1 -0
- data/app/models/pay/charge.rb +1 -1
- data/app/models/pay/subscription.rb +1 -1
- data/db/migrate/20200603134434_add_data_to_pay_models.rb +2 -11
- data/db/migrate/20210309004259_add_data_to_pay_billable.rb +1 -10
- data/db/migrate/20210714175351_add_uniqueness_to_pay_models.rb +6 -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/braintree/subscription.rb +2 -0
- data/lib/pay/env.rb +8 -0
- data/lib/pay/fake_processor/subscription.rb +2 -0
- data/lib/pay/paddle/subscription.rb +2 -0
- data/lib/pay/stripe/billable.rb +36 -44
- data/lib/pay/stripe/charge.rb +55 -2
- data/lib/pay/stripe/subscription.rb +62 -5
- 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 +13 -0
- data/lib/pay/stripe/webhooks/checkout_session_completed.rb +13 -0
- data/lib/pay/stripe/webhooks/payment_intent_succeeded.rb +2 -8
- data/lib/pay/stripe/webhooks/payment_method_attached.rb +17 -0
- data/lib/pay/stripe/webhooks/payment_method_automatically_updated.rb +17 -0
- data/lib/pay/stripe/webhooks/payment_method_detached.rb +17 -0
- data/lib/pay/stripe/webhooks/subscription_created.rb +1 -36
- data/lib/pay/stripe/webhooks/subscription_deleted.rb +1 -9
- data/lib/pay/stripe/webhooks/subscription_renewing.rb +4 -6
- data/lib/pay/stripe/webhooks/subscription_updated.rb +1 -29
- data/lib/pay/stripe.rb +6 -0
- data/lib/pay/version.rb +1 -1
- metadata +14 -6
- data/app/models/pay.rb +0 -5
- data/lib/generators/active_record/pay_generator.rb +0 -58
- data/lib/generators/active_record/templates/migration.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cb954b3125acb413cdebfcf57687b4ff9f33987c0500dd72f350c293f491322
|
4
|
+
data.tar.gz: b4f9b23d452a3ab76b21902ebcad03b2c927a7e7eb17f58c9ac06d3df22232a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60d31163be2531db82eb4eb1cd6218f83e3b88d4a2a18821f4f88f19465f9e6bf2c7215f4a3ac00348582f98b3122f3820a54bdb6d19e338d6d37e68b14e0803
|
7
|
+
data.tar.gz: 6cc782accfeea3325fb93c6c15d3044efb08de166a07c90f868fc202cbc99d6fd9eda5d07db8cb97f14edff4c1d257be6261d408deafc8d967e399b6107e1cf5
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
## Pay - Payments engine for Ruby on Rails
|
4
4
|
|
5
|
-
[![Build Status](https://github.com/pay-rails/pay/workflows/Tests/badge.svg)](https://github.com/pay-rails/pay/actions) [![Gem Version](https://badge.fury.io/rb/pay.svg)](https://badge.fury.io/rb/pay)
|
5
|
+
[![Build Status](https://github.com/pay-rails/pay/workflows/Tests/badge.svg)](https://github.com/pay-rails/pay/actions) [![Gem Version](https://badge.fury.io/rb/pay.svg)](https://badge.fury.io/rb/pay)
|
6
6
|
|
7
7
|
<img src="docs/images/stripe_partner_badge.svg" height="26px">
|
8
8
|
|
@@ -51,61 +51,49 @@ And then execute:
|
|
51
51
|
bundle
|
52
52
|
```
|
53
53
|
|
54
|
-
|
54
|
+
Next, we need to add migrations to your application, run the following migration:
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
```
|
60
|
-
|
61
|
-
#### Migrations
|
62
|
-
|
63
|
-
To add the migrations to your application, run the following migration:
|
64
|
-
|
65
|
-
`bin/rails pay:install:migrations`
|
56
|
+
````bash
|
57
|
+
bin/rails pay:install:migrations
|
58
|
+
````
|
66
59
|
|
67
|
-
>If your models rely on non integer ids (uuids for example) you will need to alter the `create_pay_subscriptions` and `create_pay_charges` migrations
|
68
|
-
> As commented in the migrations adding a type parameter to the `t.references :owner` line will ensure the `owner_id` column is of the correct type.
|
60
|
+
>If your models rely on non integer ids (uuids for example) you will need to alter the `create_pay_subscriptions` and `create_pay_charges` migrations.
|
69
61
|
|
70
62
|
We also need to run migrations to add Pay to the User, Account, Team, etc models that we want to make payments in our app.
|
71
63
|
|
72
|
-
|
64
|
+
```bash
|
65
|
+
bin/rails g pay:billable User
|
66
|
+
```
|
73
67
|
|
74
68
|
This will generate a migration to add Pay fields to our User model and automatically includes the `Pay::Billable` module in our `User` model. Repeat this for all the models you want to make payments in your app.
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
`rake db:migrate`
|
70
|
+
**Note:** An `email` attribute or method on your `Billable` model is required.
|
79
71
|
|
80
|
-
|
72
|
+
To sync customer names, your `Billable` model should respond to the `first_name` and `last_name` methods. Pay will sync these over to your Customer objects in Stripe and Braintree.
|
81
73
|
|
82
|
-
|
74
|
+
Finally, run the migrations
|
83
75
|
|
84
|
-
|
76
|
+
```bash
|
77
|
+
bin/rails db:migrate
|
78
|
+
```
|
85
79
|
|
86
|
-
|
80
|
+
> If you run into `NoMethodError (undefined method 'stripe_customer' for #<User:0x00007fbc34b9bf20>)`, fully restart your Rails application `bin/spring stop && rails s`
|
87
81
|
|
88
|
-
|
82
|
+
Lastly, make sure you've configured your ActionMailer default_url_options so Pay can generate links to for features like Stripe Checkout.
|
89
83
|
|
90
84
|
```ruby
|
91
|
-
#
|
92
|
-
|
93
|
-
include Pay::Billable
|
94
|
-
end
|
85
|
+
# config/application.rb
|
86
|
+
config.action_mailer.default_url_options = { host: "example.com" }
|
95
87
|
```
|
96
88
|
|
97
|
-
An `email` attribute or method on your `Billable` model is required.
|
98
|
-
|
99
|
-
To sync over customer names, your `Billable` model should respond to the `first_name` and `last_name` methods. Pay will sync these over to your Customer objects in Stripe and Braintree.
|
100
|
-
|
101
89
|
## Configuration
|
102
90
|
|
103
91
|
Need to make some changes to how Pay is used? You can create an initializer `config/initializers/pay.rb`
|
104
92
|
|
105
93
|
```ruby
|
106
94
|
Pay.setup do |config|
|
107
|
-
config.chargeable_class = 'Pay::Charge'
|
108
|
-
config.chargeable_table = 'pay_charges'
|
95
|
+
# config.chargeable_class = 'Pay::Charge'
|
96
|
+
# config.chargeable_table = 'pay_charges'
|
109
97
|
|
110
98
|
# For use in the receipt/refund/renewal mailers
|
111
99
|
config.business_name = "Business Name"
|
@@ -139,29 +127,63 @@ end
|
|
139
127
|
|
140
128
|
### Credentials
|
141
129
|
|
142
|
-
|
130
|
+
Pay automatically looks up credentials for each payment provider. We recommend storing them in the Rails credentials.
|
131
|
+
|
132
|
+
##### Rails Credentials & Secrets
|
133
|
+
|
134
|
+
You'll need to add your API keys to your Rails credentials. You can do this by running:
|
135
|
+
|
136
|
+
```bash
|
137
|
+
bin/rails credentials:edit --environment=development
|
138
|
+
```
|
139
|
+
|
140
|
+
They should be formatted like the following:
|
141
|
+
|
142
|
+
```yaml
|
143
|
+
stripe:
|
144
|
+
private_key: sk_test_xxxx
|
145
|
+
public_key: pk_test_yyyy
|
146
|
+
signing_secret: whsec_zzzz
|
147
|
+
|
148
|
+
braintree:
|
149
|
+
private_key: xxxx
|
150
|
+
public_key: yyyy
|
151
|
+
merchant_id: aaaa
|
152
|
+
environment: sandbox
|
153
|
+
|
154
|
+
paddle:
|
155
|
+
vendor_id: xxxx
|
156
|
+
vendor_auth_code: yyyy
|
157
|
+
public_key_base64: MII...==
|
158
|
+
environment: sandbox
|
159
|
+
```
|
160
|
+
|
161
|
+
You can also nest these credentials under the Rails environment if using a shared credentials file or secrets.
|
143
162
|
|
144
163
|
```yaml
|
145
164
|
development:
|
146
165
|
stripe:
|
147
|
-
private_key:
|
148
|
-
public_key:
|
149
|
-
signing_secret:
|
150
|
-
|
151
|
-
private_key: xxxx
|
152
|
-
public_key: yyyy
|
153
|
-
merchant_id: aaaa
|
154
|
-
environment: sandbox
|
155
|
-
paddle:
|
156
|
-
vendor_id: xxxx
|
157
|
-
vendor_auth_code: yyyy
|
158
|
-
public_key_base64: MII...==
|
159
|
-
environment: sandbox
|
166
|
+
private_key: sk_test_xxxx
|
167
|
+
public_key: pk_test_yyyy
|
168
|
+
signing_secret: whsec_zzzz
|
169
|
+
# ...
|
160
170
|
```
|
161
171
|
|
162
|
-
|
163
|
-
|
164
|
-
|
172
|
+
##### Environment Variables
|
173
|
+
|
174
|
+
Pay will also check environment variables for API keys:
|
175
|
+
|
176
|
+
* `STRIPE_PUBLIC_KEY`
|
177
|
+
* `STRIPE_PRIVATE_KEY`
|
178
|
+
* `STRIPE_SIGNING_SECRET`
|
179
|
+
* `BRAINTREE_MERCHANT_ID`
|
180
|
+
* `BRAINTREE_PUBLIC_KEY`
|
181
|
+
* `BRAINTREE_PRIVATE_KEY`
|
182
|
+
* `BRAINTREE_ENVIRONMENT`
|
183
|
+
* `PADDLE_VENDOR_ID`
|
184
|
+
* `PADDLE_VENDOR_AUTH_CODE`
|
185
|
+
* `PADDLE_PUBLIC_KEY_BASE64`
|
186
|
+
* `PADDLE_ENVIRONMENT`
|
165
187
|
|
166
188
|
### Generators
|
167
189
|
|
@@ -179,11 +201,13 @@ bin/rails generate pay:email_views
|
|
179
201
|
|
180
202
|
### Emails
|
181
203
|
|
182
|
-
Emails can be enabled/disabled using the `send_emails` configuration option (enabled
|
204
|
+
Emails can be enabled/disabled using the `send_emails` configuration option (enabled by default).
|
183
205
|
|
184
|
-
|
185
|
-
|
186
|
-
-
|
206
|
+
When enabled, the following emails will be sent when:
|
207
|
+
|
208
|
+
- A charge succeeded
|
209
|
+
- A charge was refunded
|
210
|
+
- A subscription is about to renew
|
187
211
|
|
188
212
|
|
189
213
|
## Billable API
|
@@ -588,10 +612,18 @@ If you have a catch all route (for 404s etc) and need to control where/when the
|
|
588
612
|
|
589
613
|
```ruby
|
590
614
|
# config/initializers/pay.rb
|
591
|
-
|
615
|
+
Pay.setup do |config|
|
616
|
+
# ...
|
617
|
+
|
618
|
+
config.automount_routes = false
|
619
|
+
end
|
592
620
|
|
593
621
|
# config/routes.rb
|
594
|
-
|
622
|
+
Rails.application.routes.draw do
|
623
|
+
mount Pay::Engine, at: '/pay' # You can change the `at` path to feed your needs.
|
624
|
+
|
625
|
+
# Other routes here
|
626
|
+
end
|
595
627
|
```
|
596
628
|
|
597
629
|
If you just want to modify where the engine mounts it's routes then you can change the path.
|
@@ -599,7 +631,11 @@ If you just want to modify where the engine mounts it's routes then you can chan
|
|
599
631
|
```ruby
|
600
632
|
# config/initializers/pay.rb
|
601
633
|
|
602
|
-
|
634
|
+
Pay.setup do |config|
|
635
|
+
# ...
|
636
|
+
|
637
|
+
config.routes_path = '/pay'
|
638
|
+
end
|
603
639
|
```
|
604
640
|
|
605
641
|
## Payment Providers
|
data/app/models/pay/charge.rb
CHANGED
@@ -16,7 +16,7 @@ module Pay
|
|
16
16
|
# Validations
|
17
17
|
validates :amount, presence: true
|
18
18
|
validates :processor, presence: true
|
19
|
-
validates :processor_id, presence: true
|
19
|
+
validates :processor_id, presence: true, uniqueness: {scope: :processor, case_sensitive: false}
|
20
20
|
validates :card_type, presence: true
|
21
21
|
|
22
22
|
store_accessor :data, :paddle_receipt_url
|
@@ -14,7 +14,7 @@ module Pay
|
|
14
14
|
# Validations
|
15
15
|
validates :name, presence: true
|
16
16
|
validates :processor, presence: true
|
17
|
-
validates :processor_id, presence: true
|
17
|
+
validates :processor_id, presence: true, uniqueness: {scope: :processor, case_sensitive: false}
|
18
18
|
validates :processor_plan, presence: true
|
19
19
|
validates :quantity, presence: true
|
20
20
|
validates :status, presence: true
|
@@ -1,15 +1,6 @@
|
|
1
1
|
class AddDataToPayModels < ActiveRecord::Migration[4.2]
|
2
2
|
def change
|
3
|
-
add_column :pay_subscriptions, :data,
|
4
|
-
add_column :pay_charges, :data,
|
5
|
-
end
|
6
|
-
|
7
|
-
def data_column_type
|
8
|
-
case Pay::Adapter.current_adapter
|
9
|
-
when "postgresql"
|
10
|
-
:jsonb
|
11
|
-
else
|
12
|
-
:json
|
13
|
-
end
|
3
|
+
add_column :pay_subscriptions, :data, Pay::Adapter.json_column_type
|
4
|
+
add_column :pay_charges, :data, Pay::Adapter.json_column_type
|
14
5
|
end
|
15
6
|
end
|
@@ -4,16 +4,7 @@ class AddDataToPayBillable < ActiveRecord::Migration[4.2]
|
|
4
4
|
Rails.application.eager_load!
|
5
5
|
|
6
6
|
Pay.billable_models.each do |model|
|
7
|
-
add_column model.table_name, :pay_data,
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def data_column_type
|
12
|
-
case Pay::Adapter.current_adapter
|
13
|
-
when "postgresql"
|
14
|
-
:jsonb
|
15
|
-
else
|
16
|
-
:json
|
7
|
+
add_column model.table_name, :pay_data, Pay::Adapter.json_column_type
|
17
8
|
end
|
18
9
|
end
|
19
10
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/active_record"
|
4
|
+
require "generators/pay/orm_helpers"
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
module Generators
|
8
|
+
class BillableGenerator < ActiveRecord::Generators::Base
|
9
|
+
include Pay::Generators::OrmHelpers
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
def copy_pay_billable_migration
|
13
|
+
if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
|
14
|
+
migration_template "billable_migration.rb", "#{migration_path}/add_pay_billable_to_#{table_name}.rb", migration_version: migration_version
|
15
|
+
else
|
16
|
+
say "#{model_path} does not exist.", :red
|
17
|
+
say "⚠️ Make sure the #{name} model exists before running this generator."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# If the file already contains the contents, the user will receive this warning:
|
22
|
+
#
|
23
|
+
# File unchanged! The supplied flag value not found!
|
24
|
+
#
|
25
|
+
# This can be ignored as it just means the contents already exist and the file is unchanged.
|
26
|
+
# Thor will be updated to improve this message: https://github.com/rails/thor/issues/706
|
27
|
+
def inject_pay_billable_content
|
28
|
+
return unless model_exists?
|
29
|
+
|
30
|
+
content = model_contents
|
31
|
+
class_path = (namespaced? ? class_name.to_s.split("::") : [class_name])
|
32
|
+
indent_depth = class_path.size - 1
|
33
|
+
content = content.split("\n").map { |line| " " * indent_depth + line }.join("\n") << "\n"
|
34
|
+
inject_into_class(model_path, class_path.last, content)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def model_contents
|
40
|
+
" include Pay::Billable"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/active_record"
|
4
|
+
require "generators/pay/orm_helpers"
|
5
|
+
|
6
|
+
module ActiveRecord
|
7
|
+
module Generators
|
8
|
+
class MerchantGenerator < ActiveRecord::Generators::Base
|
9
|
+
include Pay::Generators::OrmHelpers
|
10
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
|
+
|
12
|
+
def copy_pay_merchant_migration
|
13
|
+
if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
|
14
|
+
migration_template "merchant_migration.rb", "#{migration_path}/add_pay_merchant_to_#{table_name}.rb", migration_version: migration_version
|
15
|
+
else
|
16
|
+
say "#{model_path} does not exist.", :red
|
17
|
+
say "⚠️ Make sure the #{name} model exists before running this generator."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# If the file already contains the contents, the user will receive this warning:
|
22
|
+
#
|
23
|
+
# File unchanged! The supplied flag value not found!
|
24
|
+
#
|
25
|
+
# This can be ignored as it just means the contents already exist and the file is unchanged.
|
26
|
+
# Thor will be updated to improve this message: https://github.com/rails/thor/issues/706
|
27
|
+
def inject_pay_merchant_content
|
28
|
+
return unless model_exists?
|
29
|
+
|
30
|
+
content = model_contents
|
31
|
+
class_path = (namespaced? ? class_name.to_s.split("::") : [class_name])
|
32
|
+
indent_depth = class_path.size - 1
|
33
|
+
content = content.split("\n").map { |line| " " * indent_depth + line }.join("\n") << "\n"
|
34
|
+
inject_into_class(model_path, class_path.last, content)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def model_contents
|
40
|
+
" include Pay::Merchant"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPayBillableTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
def change
|
5
|
+
change_table :<%= table_name %>, bulk: true do |t|
|
6
|
+
t.string :processor
|
7
|
+
t.string :processor_id
|
8
|
+
t.public_send(Pay::Adapter.json_column_type, :pay_data)
|
9
|
+
t.datetime :trial_ends_at
|
10
|
+
t.string :card_type
|
11
|
+
t.string :card_last4
|
12
|
+
t.string :card_exp_month
|
13
|
+
t.string :card_exp_year
|
14
|
+
t.text :extra_billing_info
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddPayMerchantTo<%= table_name.camelize %> < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
def change
|
5
|
+
add_column table_name, :merchant_processor, :string
|
6
|
+
|
7
|
+
# We may already have the pay_data column if a Pay::Billable object is also a Pay::Merchant
|
8
|
+
unless ActiveRecord::Base.connection.column_exists?(table_name, :pay_data)
|
9
|
+
add_column :<%= table_name %>, :pay_data, Pay::Adapter.json_column_type
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -4,13 +4,12 @@ require "rails/generators/named_base"
|
|
4
4
|
|
5
5
|
module Pay
|
6
6
|
module Generators
|
7
|
-
class
|
7
|
+
class BillableGenerator < Rails::Generators::NamedBase
|
8
8
|
include Rails::Generators::ResourceHelpers
|
9
9
|
|
10
|
-
namespace "pay"
|
11
10
|
source_root File.expand_path("../templates", __FILE__)
|
12
11
|
|
13
|
-
desc "Generates a migration to add Billable fields to a model."
|
12
|
+
desc "Generates a migration to add Pay::Billable fields to a model."
|
14
13
|
|
15
14
|
hook_for :orm
|
16
15
|
end
|