stripe-rails 2.1.0 → 2.2.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/.github/workflows/ruby.yml +3 -0
- data/Changelog.md +4 -0
- data/README.md +36 -6
- data/Rakefile +0 -0
- data/config/routes.rb +0 -1
- data/lib/generators/stripe/install_generator.rb +1 -0
- data/lib/generators/templates/prices.rb +46 -0
- data/lib/stripe/engine.rb +1 -1
- data/lib/stripe/prices.rb +189 -0
- data/lib/stripe/rails.rb +1 -0
- data/lib/stripe/rails/tasks.rake +11 -2
- data/lib/stripe/rails/version.rb +1 -1
- data/test/dummy/config/stripe/prices.rb +59 -0
- data/test/dummy_apis_controller_spec.rb +1 -1
- data/test/fixtures/stripe_prices.json +7 -0
- data/test/plan_builder_spec.rb +1 -1
- data/test/price_builder_spec.rb +594 -0
- metadata +11 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15856817d5ce2ac1b96f1ad4f6f93602b5b80f0790cfbbd56ae87c0d89654571
|
4
|
+
data.tar.gz: 602743d7695c49114426acf961c7c7df1fd7e6d959cb1d00c860a729913847c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29127701ac3cccb96aa0bd215f616fa83b41d55cfc40d41aaafd56ca0ca0a479822b4c473bfbe3d9fdb3dfac6d0061dd93e237a7a412811358952d0c97f51f60
|
7
|
+
data.tar.gz: '07384662c64848e9e86bc592501b705e7879c8a8222dae408195b5b3b6fd8ef9e23cc6379d3f9dcd382dbe6806448a8978108f449984605de0232c81763c0423'
|
data/.github/workflows/ruby.yml
CHANGED
@@ -33,6 +33,9 @@ jobs:
|
|
33
33
|
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
34
34
|
RUBY_VERSION: ${{ matrix.ruby }}
|
35
35
|
run: |
|
36
|
+
if [ $RUBY_VERSION == "2.5.x" ] ;
|
37
|
+
then gem install bundler
|
38
|
+
fi
|
36
39
|
bundle install --jobs 4 --retry 3
|
37
40
|
bundle exec rake
|
38
41
|
if [ `basename $BUNDLE_GEMFILE` == "Gemfile" ] && [ $RUBY_VERSION == "2.7.x" ] && [ ! -z ${CC_TEST_REPORTER_ID} ] ;
|
data/Changelog.md
CHANGED
data/README.md
CHANGED
@@ -9,7 +9,7 @@ This gem can help your rails application integrate with Stripe in the following
|
|
9
9
|
|
10
10
|
* manage stripe configurations in a single place.
|
11
11
|
* makes stripe.js available from the asset pipeline.
|
12
|
-
* manage plans and coupons from within your app.
|
12
|
+
* manage product, prices, plans and coupons from within your app.
|
13
13
|
* painlessly receive and validate webhooks from stripe.
|
14
14
|
|
15
15
|
[📫 Sign up for the Newsletter](http://tinyletter.com/stripe-rails) to receive occasional updates.
|
@@ -170,6 +170,7 @@ this will generate the configuration files containing your plan and coupon defin
|
|
170
170
|
```console
|
171
171
|
create config/stripe/products.rb
|
172
172
|
create config/stripe/plans.rb
|
173
|
+
create config/stripe/prices.rb
|
173
174
|
create config/stripe/coupons.rb
|
174
175
|
```
|
175
176
|
|
@@ -267,17 +268,46 @@ Stripe.product :primo do |product|
|
|
267
268
|
end
|
268
269
|
```
|
269
270
|
|
270
|
-
|
271
|
+
And Prices:
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
Stripe.price :bronze do |price|
|
275
|
+
# Use an existing product id to prevent a new product from
|
276
|
+
# getting created
|
277
|
+
price.product_id = Stripe::Products::PRIMO.id
|
278
|
+
price.billing_scheme = 'tiered'
|
279
|
+
price.recurring = {
|
280
|
+
interval: 'month',
|
281
|
+
usage_type: 'metered'
|
282
|
+
}
|
283
|
+
|
284
|
+
# Use graduated pricing tiers
|
285
|
+
# ref: https://stripe.com/docs/api/prices/object#price_object-tiers
|
286
|
+
price.tiers = [
|
287
|
+
{
|
288
|
+
unit_amount: 1500,
|
289
|
+
up_to: 10
|
290
|
+
},
|
291
|
+
{
|
292
|
+
unit_amount: 1000,
|
293
|
+
up_to: 'inf'
|
294
|
+
}
|
295
|
+
]
|
296
|
+
price.tiers_mode = 'graduated'
|
297
|
+
end
|
298
|
+
````
|
299
|
+
|
300
|
+
To upload your plans, products, prices and coupons onto stripe.com, run:
|
271
301
|
|
272
302
|
```sh
|
273
303
|
rake stripe:prepare
|
274
304
|
```
|
275
305
|
|
276
|
-
This will create any plans and coupons that do not currently exist, and treat as a NOOP any
|
277
|
-
|
278
|
-
use any of these
|
306
|
+
This will create any plans, products, prices and coupons that do not currently exist, and treat as a NOOP any
|
307
|
+
objects that already exist, so you can run this command safely as many times as you wish. Now you can
|
308
|
+
use any of these objects in your application.
|
279
309
|
|
280
|
-
NOTE: You must destroy plans manually from your stripe dashboard.
|
310
|
+
NOTE: You must destroy plans and prices manually from your stripe dashboard.
|
281
311
|
|
282
312
|
## Stripe Elements
|
283
313
|
|
data/Rakefile
CHANGED
File without changes
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
# This file contains descriptions of all your stripe prices
|
2
|
+
|
3
|
+
# Example
|
4
|
+
# Stripe::Prices::LITE.lookup_key #=> 'lite'
|
5
|
+
|
6
|
+
# Prices will have a stripe generated id. The lookup_key will match the
|
7
|
+
# configuration below. You can fetch the ID or object from stripe:
|
8
|
+
#
|
9
|
+
# Stripe::Prices::LITE.stripe_id #=> 'price_0000sdfs2qfsdf'
|
10
|
+
# Stripe::Prices::LITE.stripe_object #=> #<Stripe::Price:0x3584 id=price_0000sdfs2qfsdf>...
|
11
|
+
|
12
|
+
# Prices are not deletable via the API, the `reset!` method will instead
|
13
|
+
# create a new price and transfer the lookup key to the new price.
|
14
|
+
|
15
|
+
# Stripe.price :lite do |price|
|
16
|
+
# # Prices may belong to a product, this will create a product along with the price
|
17
|
+
# price.name = 'Acme as a service LITE'
|
18
|
+
|
19
|
+
# # You can also specify an existing product ID
|
20
|
+
# # price.product_id = Stripe::Products::PRIMO.id
|
21
|
+
#
|
22
|
+
# # amount in cents. This is 6.99
|
23
|
+
# price.unit_amount = 699
|
24
|
+
#
|
25
|
+
# # currency to use for the price (default 'usd')
|
26
|
+
# price.currency = 'usd'
|
27
|
+
#
|
28
|
+
# price.recurring = {
|
29
|
+
# # interval must be either 'day', 'week', 'month' or 'year'
|
30
|
+
# interval: 'month',
|
31
|
+
# # only bill once every three months (default 1)
|
32
|
+
# interval_count: 3,
|
33
|
+
# # Must be either 'metered' or 'licensed'
|
34
|
+
# usage_type: 'metered',
|
35
|
+
# # Specifies a usage aggregation strategy for metered usage
|
36
|
+
# aggregate_usage: 'sum'
|
37
|
+
# }
|
38
|
+
#
|
39
|
+
# end
|
40
|
+
|
41
|
+
# Once you have your prices defined, you can run
|
42
|
+
#
|
43
|
+
# rake stripe:prepare
|
44
|
+
#
|
45
|
+
# This will export any new prices to stripe.com so that you can
|
46
|
+
# begin using them in your API calls.
|
data/lib/stripe/engine.rb
CHANGED
@@ -89,7 +89,7 @@ environment file directly.
|
|
89
89
|
end
|
90
90
|
|
91
91
|
initializer 'stripe.plans_and_coupons' do |app|
|
92
|
-
for configuration in %w(products plans coupons)
|
92
|
+
for configuration in %w(products plans coupons prices)
|
93
93
|
path = app.root.join("config/stripe/#{configuration}.rb")
|
94
94
|
load path if path.exist?
|
95
95
|
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
module Stripe
|
2
|
+
module Prices
|
3
|
+
include ConfigurationBuilder
|
4
|
+
VALID_TIME_UNITS = %i(day week month year)
|
5
|
+
|
6
|
+
configuration_for :price do
|
7
|
+
attr_reader :lookup_key
|
8
|
+
attr_accessor :active,
|
9
|
+
:billing_scheme,
|
10
|
+
:constant_name,
|
11
|
+
:currency,
|
12
|
+
:metadata,
|
13
|
+
:name,
|
14
|
+
:nickname,
|
15
|
+
:object,
|
16
|
+
:product_id,
|
17
|
+
:recurring,
|
18
|
+
:statement_descriptor,
|
19
|
+
:tiers,
|
20
|
+
:tiers_mode,
|
21
|
+
:transform_quantity,
|
22
|
+
:type,
|
23
|
+
:unit_amount
|
24
|
+
|
25
|
+
validates_presence_of :id, :currency
|
26
|
+
validates_presence_of :unit_amount, unless: ->(p) { p.billing_scheme == 'tiered' }
|
27
|
+
validates_absence_of :transform_quantity, if: ->(p) { p.billing_scheme == 'tiered' }
|
28
|
+
validates_presence_of :tiers_mode, :tiers, if: ->(p) { p.billing_scheme == 'tiered' }
|
29
|
+
|
30
|
+
validates_numericality_of :recurring_interval_count, allow_nil: true
|
31
|
+
|
32
|
+
validates_inclusion_of :recurring_interval,
|
33
|
+
in: VALID_TIME_UNITS.collect(&:to_s),
|
34
|
+
message: "'%{value}' is not one of #{VALID_TIME_UNITS.to_sentence(last_word_connector: ', or ')}",
|
35
|
+
if: ->(p) { p.recurring.present? }
|
36
|
+
|
37
|
+
validates :statement_descriptor, length: { maximum: 22 }
|
38
|
+
|
39
|
+
validates :active, inclusion: { in: [true, false] }, allow_nil: true
|
40
|
+
validates :billing_scheme, inclusion: { in: %w{ per_unit tiered } }, allow_nil: true
|
41
|
+
validates :recurring_aggregate_usage, inclusion: { in: %w{ sum last_during_period last_ever max } }, allow_nil: true
|
42
|
+
validates :recurring_usage_type, inclusion: { in: %w{ metered licensed } }, allow_nil: true
|
43
|
+
validates :tiers_mode, inclusion: { in: %w{ graduated volume } }, allow_nil: true
|
44
|
+
|
45
|
+
validate :name_or_product_id
|
46
|
+
validate :recurring_aggregate_usage_must_be_metered, if: ->(p) { p.recurring_aggregate_usage.present? }
|
47
|
+
validate :recurring_interval_count_maximum, if: ->(p) { p.recurring_interval_count.present? }
|
48
|
+
validate :valid_constant_name, unless: ->(p) { p.constant_name.nil? }
|
49
|
+
|
50
|
+
# validations for when using tiered billing
|
51
|
+
validate :tiers_must_be_array, if: ->(p) { p.tiers.present? }
|
52
|
+
validate :billing_scheme_must_be_tiered, if: ->(p) { p.tiers.present? }
|
53
|
+
validate :validate_tiers, if: ->(p) { p.billing_scheme == 'tiered' }
|
54
|
+
|
55
|
+
def initialize(*args)
|
56
|
+
super(*args)
|
57
|
+
@currency = 'usd'
|
58
|
+
@lookup_key = @id.to_s
|
59
|
+
@recurring = (recurring || {}).symbolize_keys
|
60
|
+
end
|
61
|
+
|
62
|
+
# We're overriding a handful of the Configuration methods so that
|
63
|
+
# we find and create by lookup_key instead of by ID. The ID is assigned
|
64
|
+
# by stripe and out of our control
|
65
|
+
def put!
|
66
|
+
if exists?
|
67
|
+
puts "[EXISTS] - #{@stripe_class}:#{@id}:#{stripe_id}" unless Stripe::Engine.testing
|
68
|
+
else
|
69
|
+
object = @stripe_class.create({:lookup_key => @lookup_key}.merge compact_create_options)
|
70
|
+
puts "[CREATE] - #{@stripe_class}:#{object}" unless Stripe::Engine.testing
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# You can't delete prices, but you can transfer the lookup key to a new price
|
75
|
+
def reset!
|
76
|
+
object = @stripe_class.create(reset_options)
|
77
|
+
puts "[RESET] - #{@stripe_class}:#{object}" unless Stripe::Engine.testing
|
78
|
+
end
|
79
|
+
|
80
|
+
def exists?
|
81
|
+
stripe_object.presence
|
82
|
+
rescue Stripe::InvalidRequestError
|
83
|
+
false
|
84
|
+
end
|
85
|
+
|
86
|
+
def stripe_object
|
87
|
+
@stripe_class.list({lookup_keys: [@lookup_key]}).data.first.presence || nil
|
88
|
+
rescue Stripe::InvalidRequestError
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def stripe_id
|
93
|
+
@stripe_id ||= stripe_object.try(:id)
|
94
|
+
end
|
95
|
+
|
96
|
+
def recurring_interval
|
97
|
+
recurring[:interval]
|
98
|
+
end
|
99
|
+
|
100
|
+
def recurring_aggregate_usage
|
101
|
+
recurring[:aggregate_usage]
|
102
|
+
end
|
103
|
+
|
104
|
+
def recurring_usage_type
|
105
|
+
recurring[:usage_type]
|
106
|
+
end
|
107
|
+
|
108
|
+
def recurring_interval_count
|
109
|
+
recurring[:interval_count]
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
def recurring_aggregate_usage_must_be_metered
|
114
|
+
errors.add(:recurring_aggregate_usage, 'recurring[:usage_type] must be metered') unless (recurring_usage_type == 'metered')
|
115
|
+
end
|
116
|
+
|
117
|
+
def recurring_interval_count_maximum
|
118
|
+
time_unit = recurring_interval.to_sym
|
119
|
+
|
120
|
+
return unless VALID_TIME_UNITS.include?(time_unit) && recurring_interval_count.respond_to?(time_unit)
|
121
|
+
too_long = recurring_interval_count.send(time_unit) > 1.year
|
122
|
+
|
123
|
+
errors.add(:recurring_interval_count, 'recurring[:interval_count] Maximum is one year (1 year, 12 months, or 52 weeks') if too_long
|
124
|
+
end
|
125
|
+
|
126
|
+
def name_or_product_id
|
127
|
+
errors.add(:base, 'must have a product_id or a name') unless (@product_id.present? ^ @name.present?)
|
128
|
+
end
|
129
|
+
|
130
|
+
def billing_scheme_must_be_tiered
|
131
|
+
errors.add(:billing_scheme, 'must be set to `tiered` when specifying `tiers`') unless billing_scheme == 'tiered'
|
132
|
+
end
|
133
|
+
|
134
|
+
def tiers_must_be_array
|
135
|
+
errors.add(:tiers, 'must be an Array') unless tiers.is_a?(Array)
|
136
|
+
end
|
137
|
+
|
138
|
+
def billing_tiers
|
139
|
+
@billing_tiers = tiers.map { |t| Stripe::Plans::BillingTier.new(t) } if tiers
|
140
|
+
end
|
141
|
+
|
142
|
+
def validate_tiers
|
143
|
+
billing_tiers.all?(&:valid?)
|
144
|
+
end
|
145
|
+
|
146
|
+
module ConstTester; end
|
147
|
+
def valid_constant_name
|
148
|
+
ConstTester.const_set(constant_name.to_s.upcase, constant_name)
|
149
|
+
ConstTester.send(:remove_const, constant_name.to_s.upcase.to_sym)
|
150
|
+
rescue NameError
|
151
|
+
errors.add(:constant_name, 'is not a valid Ruby constant name.')
|
152
|
+
end
|
153
|
+
|
154
|
+
def reset_options
|
155
|
+
existing_object = stripe_object
|
156
|
+
# Lookup and set the existing product ID if unset
|
157
|
+
@product_id ||= existing_object.product if existing_object.present?
|
158
|
+
|
159
|
+
{ transfer_lookup_key: existing_object.present? }.merge(compact_create_options)
|
160
|
+
end
|
161
|
+
|
162
|
+
def create_options
|
163
|
+
{
|
164
|
+
currency: currency,
|
165
|
+
unit_amount: unit_amount,
|
166
|
+
active: active,
|
167
|
+
metadata: metadata,
|
168
|
+
nickname: nickname.presence || @lookup_key,
|
169
|
+
recurring: recurring.compact,
|
170
|
+
tiers: tiers ? tiers.map(&:to_h) : nil,
|
171
|
+
tiers_mode: tiers_mode,
|
172
|
+
billing_scheme: billing_scheme,
|
173
|
+
lookup_key: @lookup_key,
|
174
|
+
transform_quantity: transform_quantity,
|
175
|
+
}.merge(product_options).compact
|
176
|
+
end
|
177
|
+
|
178
|
+
def product_options
|
179
|
+
if product_id.present?
|
180
|
+
{ product: product_id }
|
181
|
+
else
|
182
|
+
{
|
183
|
+
product_data: { name: name, statement_descriptor: statement_descriptor }
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/lib/stripe/rails.rb
CHANGED
data/lib/stripe/rails/tasks.rake
CHANGED
@@ -30,6 +30,15 @@ namespace :stripe do
|
|
30
30
|
Stripe::Coupons.reset!
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
task 'prices:prepare' => 'environment' do
|
34
|
+
Stripe::Prices.put!
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'delete and redefine all prices defined in config/stripe/prices.rb'
|
38
|
+
task 'prices:reset!' => 'environment' do
|
39
|
+
Stripe::Prices.reset!
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "create all plans and coupons defined in config/stripe/{products|plans|prices|coupons}.rb"
|
43
|
+
task 'prepare' => ['products:prepare', 'plans:prepare', 'prices:prepare', 'coupons:prepare']
|
35
44
|
end
|
data/lib/stripe/rails/version.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
Stripe.price :gold do |price|
|
2
|
+
price.name = 'Solid Gold'
|
3
|
+
price.unit_amount = 699
|
4
|
+
price.recurring = {
|
5
|
+
interval: 'month'
|
6
|
+
}
|
7
|
+
end
|
8
|
+
|
9
|
+
Stripe.price "Solid Gold".to_sym do |price|
|
10
|
+
price.constant_name = 'SOLID_GOLD'
|
11
|
+
price.name = 'Solid Gold'
|
12
|
+
price.unit_amount = 699
|
13
|
+
price.recurring = {
|
14
|
+
interval: 'month'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
Stripe.price :alternative_currency do |price|
|
19
|
+
price.name = 'Alternative Currency'
|
20
|
+
price.unit_amount = 699
|
21
|
+
price.recurring = {
|
22
|
+
interval: 'month'
|
23
|
+
}
|
24
|
+
price.currency = 'cad'
|
25
|
+
end
|
26
|
+
|
27
|
+
Stripe.price :metered do |price|
|
28
|
+
price.name = 'Metered'
|
29
|
+
price.unit_amount = 699
|
30
|
+
price.recurring = {
|
31
|
+
interval: 'month',
|
32
|
+
aggregate_usage: 'max',
|
33
|
+
usage_type: 'metered'
|
34
|
+
}
|
35
|
+
price.billing_scheme = 'per_unit'
|
36
|
+
end
|
37
|
+
|
38
|
+
Stripe.price :tiered do |price|
|
39
|
+
price.name = 'Tiered'
|
40
|
+
price.billing_scheme = 'tiered'
|
41
|
+
# interval must be either 'day', 'week', 'month' or 'year'
|
42
|
+
price.recurring = {
|
43
|
+
interval: 'month',
|
44
|
+
interval_count: 2,
|
45
|
+
aggregate_usage: 'max',
|
46
|
+
usage_type: 'metered'
|
47
|
+
}
|
48
|
+
price.tiers = [
|
49
|
+
{
|
50
|
+
unit_amount: 1500,
|
51
|
+
up_to: 10
|
52
|
+
},
|
53
|
+
{
|
54
|
+
unit_amount: 1000,
|
55
|
+
up_to: 'inf'
|
56
|
+
}
|
57
|
+
]
|
58
|
+
price.tiers_mode = 'graduated'
|
59
|
+
end
|
data/test/plan_builder_spec.rb
CHANGED
@@ -140,7 +140,7 @@ describe 'building plans' do
|
|
140
140
|
}).must_raise Stripe::InvalidConfigurationError
|
141
141
|
end
|
142
142
|
|
143
|
-
it 'denies aggregate_usage if usage type is
|
143
|
+
it 'denies aggregate_usage if usage type is licensed' do
|
144
144
|
_(lambda {
|
145
145
|
Stripe.plan :broken do |plan|
|
146
146
|
plan.name = 'Acme as a service'
|
@@ -0,0 +1,594 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'building prices' do
|
4
|
+
describe 'simply' do
|
5
|
+
before do
|
6
|
+
Stripe.price :lite do |price|
|
7
|
+
price.name = 'Acme as a service LITE'
|
8
|
+
price.unit_amount = 699
|
9
|
+
price.recurring = {
|
10
|
+
interval: 'month',
|
11
|
+
interval_count: 3,
|
12
|
+
usage_type: 'metered',
|
13
|
+
aggregate_usage: 'sum'
|
14
|
+
}
|
15
|
+
price.metadata = {:number_of_awesome_things => 5}
|
16
|
+
price.statement_descriptor = 'Acme Lite'
|
17
|
+
price.active = true
|
18
|
+
price.nickname = 'lite'
|
19
|
+
price.billing_scheme = 'per_unit'
|
20
|
+
price.tiers_mode = 'graduated'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
after { Stripe::Prices.send(:remove_const, :LITE) }
|
25
|
+
|
26
|
+
it 'is accessible via id' do
|
27
|
+
_(Stripe::Prices::LITE).wont_be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'is accessible via collection' do
|
31
|
+
_(Stripe::Prices.all).must_include Stripe::Prices::LITE
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'is accessible via hash lookup (symbol/string agnostic)' do
|
35
|
+
_(Stripe::Prices[:lite]).must_equal Stripe::Prices::LITE
|
36
|
+
_(Stripe::Prices['lite']).must_equal Stripe::Prices::LITE
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'sets the lookup key' do
|
40
|
+
_(Stripe::Prices::LITE.lookup_key).must_equal 'lite'
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'accepts a billing interval of a day' do
|
44
|
+
Stripe.price :daily do |price|
|
45
|
+
price.name = 'Acme as a service daily'
|
46
|
+
price.unit_amount = 100
|
47
|
+
price.recurring = {
|
48
|
+
interval: 'day'
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
_(Stripe::Prices::DAILY).wont_be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'denies a billing interval of a day and excessive intervals' do
|
56
|
+
_(lambda {
|
57
|
+
Stripe.price :broken do |price|
|
58
|
+
price.name = 'Acme as a service daily'
|
59
|
+
price.unit_amount = 100
|
60
|
+
price.recurring = {
|
61
|
+
interval: 'day',
|
62
|
+
interval_count: 366
|
63
|
+
}
|
64
|
+
end
|
65
|
+
}).must_raise Stripe::InvalidConfigurationError
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'accepts a billing interval of a week' do
|
69
|
+
Stripe.price :weekly do |price|
|
70
|
+
price.name = 'Acme as a service weekly'
|
71
|
+
price.unit_amount = 100
|
72
|
+
price.recurring = {
|
73
|
+
interval: 'week'
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
_(Stripe::Prices::WEEKLY).wont_be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'denies a billing interval of a week and excessive intervals' do
|
81
|
+
_(lambda {
|
82
|
+
Stripe.price :broken do |price|
|
83
|
+
price.name = 'Acme as a service weekly'
|
84
|
+
price.unit_amount = 100
|
85
|
+
price.recurring = {
|
86
|
+
interval: 'week',
|
87
|
+
interval_count: 53
|
88
|
+
}
|
89
|
+
end
|
90
|
+
}).must_raise Stripe::InvalidConfigurationError
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'accepts a billing interval of a month' do
|
94
|
+
Stripe.price :monthly do |price|
|
95
|
+
price.name = 'Acme as a service monthly'
|
96
|
+
price.unit_amount = 400
|
97
|
+
price.recurring = {
|
98
|
+
interval: 'month'
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
_(Stripe::Prices::MONTHLY).wont_be_nil
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'denies a billing interval of a month and excessive intervals' do
|
106
|
+
_(lambda {
|
107
|
+
Stripe.price :broken do |price|
|
108
|
+
price.name = 'Acme as a service monthly'
|
109
|
+
price.unit_amount = 400
|
110
|
+
price.recurring = {
|
111
|
+
interval: 'month',
|
112
|
+
interval_count: 13
|
113
|
+
}
|
114
|
+
end
|
115
|
+
}).must_raise Stripe::InvalidConfigurationError
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'accepts a billing interval of a year' do
|
119
|
+
Stripe.price :yearly do |price|
|
120
|
+
price.name = 'Acme as a service yearly'
|
121
|
+
price.unit_amount = 4800
|
122
|
+
price.recurring = {
|
123
|
+
interval: 'year'
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
_(Stripe::Prices::YEARLY).wont_be_nil
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'denies a billing interval of a year and excessive intervals' do
|
131
|
+
_(lambda {
|
132
|
+
Stripe.price :broken do |price|
|
133
|
+
price.name = 'Acme as a service yearly'
|
134
|
+
price.unit_amount = 4800
|
135
|
+
price.recurring = {
|
136
|
+
interval: 'year',
|
137
|
+
interval_count: 2
|
138
|
+
}
|
139
|
+
end
|
140
|
+
}).must_raise Stripe::InvalidConfigurationError
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'denies arbitrary billing intervals' do
|
144
|
+
_(lambda {
|
145
|
+
Stripe.price :broken do |price|
|
146
|
+
price.name = 'Acme as a service BROKEN'
|
147
|
+
price.unit_amount = 999
|
148
|
+
price.recurring = {
|
149
|
+
interval: 'anything'
|
150
|
+
}
|
151
|
+
end
|
152
|
+
}).must_raise Stripe::InvalidConfigurationError
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'accepts empty recurring options' do
|
156
|
+
Stripe.price :singular do |price|
|
157
|
+
price.name = 'Acme as a service one time'
|
158
|
+
price.unit_amount = 888
|
159
|
+
end
|
160
|
+
|
161
|
+
_(Stripe::Prices::SINGULAR).wont_be_nil
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'accepts a statement descriptor' do
|
165
|
+
Stripe.price :described do |price|
|
166
|
+
price.name = 'Acme as a service'
|
167
|
+
price.unit_amount = 999
|
168
|
+
price.recurring = {
|
169
|
+
interval: 'month'
|
170
|
+
}
|
171
|
+
price.statement_descriptor = 'ACME Monthly'
|
172
|
+
end
|
173
|
+
|
174
|
+
_(Stripe::Prices::DESCRIBED).wont_be_nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'denies statement descriptors that are too long' do
|
178
|
+
_(lambda {
|
179
|
+
Stripe.price :described do |price|
|
180
|
+
price.name = 'Acme as a service'
|
181
|
+
price.unit_amount = 999
|
182
|
+
price.recurring = {
|
183
|
+
interval: 'month'
|
184
|
+
}
|
185
|
+
price.statement_descriptor = 'ACME as a Service Monthly'
|
186
|
+
end
|
187
|
+
}).must_raise Stripe::InvalidConfigurationError
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'denies invalid values for active' do
|
191
|
+
_(lambda {
|
192
|
+
Stripe.price :broken do |price|
|
193
|
+
price.name = 'Acme as a service'
|
194
|
+
price.unit_amount = 999
|
195
|
+
price.recurring = {
|
196
|
+
interval: 'month'
|
197
|
+
}
|
198
|
+
price.active = 'whatever'
|
199
|
+
end
|
200
|
+
}).must_raise Stripe::InvalidConfigurationError
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'denies invalid values for usage_type' do
|
204
|
+
_(lambda {
|
205
|
+
Stripe.price :broken do |price|
|
206
|
+
price.name = 'Acme as a service'
|
207
|
+
price.unit_amount = 999
|
208
|
+
price.recurring = {
|
209
|
+
interval: 'month',
|
210
|
+
usage_type: 'whatever'
|
211
|
+
}
|
212
|
+
end
|
213
|
+
}).must_raise Stripe::InvalidConfigurationError
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'denies invalid values for aggregate_usage' do
|
217
|
+
_(lambda {
|
218
|
+
Stripe.price :broken do |price|
|
219
|
+
price.name = 'Acme as a service'
|
220
|
+
price.unit_amount = 999
|
221
|
+
price.recurring = {
|
222
|
+
interval: 'month',
|
223
|
+
aggregate_usage: 'whatever'
|
224
|
+
}
|
225
|
+
end
|
226
|
+
}).must_raise Stripe::InvalidConfigurationError
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'denies aggregate_usage if usage type is licensed' do
|
230
|
+
_(lambda {
|
231
|
+
Stripe.price :broken do |price|
|
232
|
+
price.name = 'Acme as a service'
|
233
|
+
price.unit_amount = 999
|
234
|
+
price.recurring = {
|
235
|
+
interval: 'month',
|
236
|
+
usage_type: 'licensed',
|
237
|
+
aggregate_usage: 'sum'
|
238
|
+
}
|
239
|
+
end
|
240
|
+
}).must_raise Stripe::InvalidConfigurationError
|
241
|
+
end
|
242
|
+
|
243
|
+
|
244
|
+
it 'denies invalid values for billing_scheme' do
|
245
|
+
_(lambda {
|
246
|
+
Stripe.price :broken do |price|
|
247
|
+
price.name = 'Acme as a service'
|
248
|
+
price.unit_amount = 999
|
249
|
+
price.recurring = {
|
250
|
+
interval: 'month'
|
251
|
+
}
|
252
|
+
price.billing_scheme = 'whatever'
|
253
|
+
end
|
254
|
+
}).must_raise Stripe::InvalidConfigurationError
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'denies invalid values for tiers_mode' do
|
258
|
+
_(lambda {
|
259
|
+
Stripe.price :broken do |price|
|
260
|
+
price.name = 'Acme as a service'
|
261
|
+
price.unit_amount = 999
|
262
|
+
price.recurring = {
|
263
|
+
interval: 'month'
|
264
|
+
}
|
265
|
+
price.tiers_mode = 'whatever'
|
266
|
+
end
|
267
|
+
}).must_raise Stripe::InvalidConfigurationError
|
268
|
+
end
|
269
|
+
|
270
|
+
describe 'name and product id validation' do
|
271
|
+
it 'should be valid when using just the product id' do
|
272
|
+
Stripe.price :prodded do |price|
|
273
|
+
price.product_id = 'acme'
|
274
|
+
price.unit_amount = 999
|
275
|
+
price.recurring = {
|
276
|
+
interval: 'month'
|
277
|
+
}
|
278
|
+
end
|
279
|
+
_(Stripe::Prices::PRODDED).wont_be_nil
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should be invalid when using both name and product id' do
|
283
|
+
_(lambda {
|
284
|
+
Stripe.price :broken do |price|
|
285
|
+
price.name = 'Acme as a service'
|
286
|
+
price.product_id = 'acme'
|
287
|
+
price.unit_amount = 999
|
288
|
+
price.recurring = {
|
289
|
+
interval: 'month'
|
290
|
+
}
|
291
|
+
end
|
292
|
+
}).must_raise Stripe::InvalidConfigurationError
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe 'uploading' do
|
297
|
+
include FixtureLoader
|
298
|
+
|
299
|
+
describe 'when none exists on stripe.com' do
|
300
|
+
before do
|
301
|
+
Stripe::Price.stubs(:list).returns(Stripe::Price.construct_from(data: []))
|
302
|
+
|
303
|
+
stub_request(:get, "https://api.stripe.com/v1/prices").
|
304
|
+
with(headers: { 'Authorization'=>'Bearer XYZ',}).
|
305
|
+
to_return(status: 200, body: load_request_fixture('stripe_prices.json'))
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'creates the price online' do
|
309
|
+
Stripe::Price.expects(:create).with(
|
310
|
+
:lookup_key => 'gold',
|
311
|
+
:nickname => 'gold',
|
312
|
+
:currency => 'usd',
|
313
|
+
:product_data => {
|
314
|
+
:name => 'Solid Gold',
|
315
|
+
:statement_descriptor => nil
|
316
|
+
},
|
317
|
+
:unit_amount => 699,
|
318
|
+
:recurring => {
|
319
|
+
:interval => 'month'
|
320
|
+
}
|
321
|
+
)
|
322
|
+
Stripe::Prices::GOLD.put!
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'creates a price with an alternative currency' do
|
326
|
+
Stripe::Price.expects(:create).with(
|
327
|
+
:lookup_key => 'alternative_currency',
|
328
|
+
:nickname => 'alternative_currency',
|
329
|
+
:currency => 'cad',
|
330
|
+
:product_data => {
|
331
|
+
:name => 'Alternative Currency',
|
332
|
+
:statement_descriptor => nil
|
333
|
+
},
|
334
|
+
:unit_amount => 699,
|
335
|
+
:recurring => {
|
336
|
+
:interval => 'month'
|
337
|
+
}
|
338
|
+
)
|
339
|
+
Stripe::Prices::ALTERNATIVE_CURRENCY.put!
|
340
|
+
end
|
341
|
+
|
342
|
+
it 'creates a metered price' do
|
343
|
+
Stripe::Price.expects(:create).with(
|
344
|
+
:lookup_key => 'metered',
|
345
|
+
:nickname => 'metered',
|
346
|
+
:currency => 'usd',
|
347
|
+
:product_data => {
|
348
|
+
:name => 'Metered',
|
349
|
+
:statement_descriptor => nil,
|
350
|
+
},
|
351
|
+
:unit_amount => 699,
|
352
|
+
:recurring => {
|
353
|
+
:interval => 'month',
|
354
|
+
:usage_type => 'metered',
|
355
|
+
:aggregate_usage => 'max',
|
356
|
+
},
|
357
|
+
:billing_scheme => 'per_unit'
|
358
|
+
)
|
359
|
+
Stripe::Prices::METERED.put!
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'creates a tiered price' do
|
363
|
+
Stripe::Price.expects(:create).with(
|
364
|
+
:lookup_key => 'tiered',
|
365
|
+
:nickname => 'tiered',
|
366
|
+
:currency => 'usd',
|
367
|
+
:product_data => {
|
368
|
+
:name => 'Tiered',
|
369
|
+
:statement_descriptor => nil,
|
370
|
+
},
|
371
|
+
:recurring => {
|
372
|
+
:interval => 'month',
|
373
|
+
:interval_count => 2,
|
374
|
+
:usage_type => 'metered',
|
375
|
+
:aggregate_usage => 'max'
|
376
|
+
},
|
377
|
+
:billing_scheme => 'tiered',
|
378
|
+
:tiers => [
|
379
|
+
{
|
380
|
+
:unit_amount => 1500,
|
381
|
+
:up_to => 10
|
382
|
+
},
|
383
|
+
{
|
384
|
+
:unit_amount => 1000,
|
385
|
+
:up_to => 'inf'
|
386
|
+
}
|
387
|
+
],
|
388
|
+
:tiers_mode => 'graduated'
|
389
|
+
)
|
390
|
+
Stripe::Prices::TIERED.put!
|
391
|
+
end
|
392
|
+
|
393
|
+
describe 'when passed invalid arguments for tiered pricing' do
|
394
|
+
it 'raises a Stripe::InvalidConfigurationError when billing tiers are invalid' do
|
395
|
+
lambda {
|
396
|
+
Stripe.price "Bad Tiers".to_sym do |price|
|
397
|
+
price.name = 'Acme as a service BAD TIERS'
|
398
|
+
price.constant_name = 'BAD_TIERS'
|
399
|
+
price.recurring = {
|
400
|
+
interval: 'month',
|
401
|
+
interval_count: 1,
|
402
|
+
usage_type: 'metered',
|
403
|
+
aggregate_usage: 'sum'
|
404
|
+
}
|
405
|
+
price.tiers_mode = 'graduated'
|
406
|
+
price.billing_scheme = 'per_unit'
|
407
|
+
price.tiers = [
|
408
|
+
{
|
409
|
+
unit_amount: 1500,
|
410
|
+
up_to: 10
|
411
|
+
},
|
412
|
+
{
|
413
|
+
unit_amount: 1000,
|
414
|
+
}
|
415
|
+
]
|
416
|
+
end
|
417
|
+
}.must_raise Stripe::InvalidConfigurationError
|
418
|
+
end
|
419
|
+
|
420
|
+
it 'raises a Stripe::InvalidConfigurationError when billing tiers is not an array' do
|
421
|
+
lambda {
|
422
|
+
Stripe.price "Bad Tiers".to_sym do |price|
|
423
|
+
price.name = 'Acme as a service BAD TIERS'
|
424
|
+
price.constant_name = 'BAD_TIERS'
|
425
|
+
price.recurring = {
|
426
|
+
interval: 'month',
|
427
|
+
interval_count: 1,
|
428
|
+
usage_type: 'metered',
|
429
|
+
aggregate_usage: 'sum'
|
430
|
+
}
|
431
|
+
price.tiers_mode = 'graduated'
|
432
|
+
price.billing_scheme = 'per_unit'
|
433
|
+
price.tiers = {
|
434
|
+
unit_amount: 1500,
|
435
|
+
up_to: 10
|
436
|
+
}
|
437
|
+
end
|
438
|
+
}.must_raise Stripe::InvalidConfigurationError
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
describe 'when using a product id' do
|
443
|
+
before do
|
444
|
+
Stripe::Prices::GOLD.product_id = 'prod_XXXXXXXXXXXXXX'
|
445
|
+
Stripe::Prices::GOLD.name = nil
|
446
|
+
end
|
447
|
+
after do
|
448
|
+
Stripe::Prices::GOLD.product_id = nil
|
449
|
+
Stripe::Prices::GOLD.name = 'Solid Gold'
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'creates the price online with the product id' do
|
453
|
+
Stripe::Price.expects(:create).with(
|
454
|
+
:lookup_key => 'gold',
|
455
|
+
:nickname => 'gold',
|
456
|
+
:currency => 'usd',
|
457
|
+
:product => 'prod_XXXXXXXXXXXXXX',
|
458
|
+
:unit_amount => 699,
|
459
|
+
:recurring => {
|
460
|
+
:interval => 'month'
|
461
|
+
}
|
462
|
+
)
|
463
|
+
Stripe::Prices::GOLD.put!
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
describe 'when it is already present on stripe.com' do
|
469
|
+
before do
|
470
|
+
Stripe::Prices::GOLD.product_id = nil
|
471
|
+
Stripe::Price.stubs(:list).returns(Stripe::Price.construct_from(
|
472
|
+
data: [{
|
473
|
+
:lookup_key => 'gold',
|
474
|
+
:product => 'prod_XXXXXXXXXXXXXX'
|
475
|
+
}]))
|
476
|
+
end
|
477
|
+
after do
|
478
|
+
Stripe::Prices::GOLD.product_id = nil
|
479
|
+
end
|
480
|
+
|
481
|
+
|
482
|
+
it 'is a no-op on put!' do
|
483
|
+
Stripe::Price.expects(:create).never
|
484
|
+
Stripe::Prices::GOLD.put!
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'transfers lookup key on reset!' do
|
488
|
+
Stripe::Price.expects(:create).with(
|
489
|
+
:lookup_key => 'gold',
|
490
|
+
:transfer_lookup_key => true,
|
491
|
+
:nickname => 'gold',
|
492
|
+
:currency => 'usd',
|
493
|
+
:product => 'prod_XXXXXXXXXXXXXX',
|
494
|
+
:unit_amount => 699,
|
495
|
+
:recurring => {
|
496
|
+
:interval => 'month'
|
497
|
+
}
|
498
|
+
)
|
499
|
+
|
500
|
+
Stripe::Prices::GOLD.reset!
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe 'with missing mandatory values' do
|
507
|
+
it 'raises an exception after configuring it' do
|
508
|
+
_(-> { Stripe.price(:bad) {} }).must_raise Stripe::InvalidConfigurationError
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
describe 'with custom constant name' do
|
513
|
+
before do
|
514
|
+
Stripe.price "Lite price".to_sym do |price|
|
515
|
+
price.name = 'Acme as a service LITE'
|
516
|
+
price.constant_name = 'LITE_PRICE'
|
517
|
+
price.unit_amount = 699
|
518
|
+
price.recurring = {
|
519
|
+
interval: 'month',
|
520
|
+
interval_count: 3,
|
521
|
+
usage_type: 'metered',
|
522
|
+
aggregate_usage: 'sum'
|
523
|
+
}
|
524
|
+
price.metadata = {:number_of_awesome_things => 5}
|
525
|
+
price.statement_descriptor = 'Acme Lite'
|
526
|
+
price.active = true
|
527
|
+
price.nickname = 'lite'
|
528
|
+
price.billing_scheme = 'per_unit'
|
529
|
+
price.tiers_mode = 'graduated'
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
after { Stripe::Prices.send(:remove_const, :LITE_PRICE) }
|
534
|
+
|
535
|
+
it 'is accessible via upcased constant_name' do
|
536
|
+
_(Stripe::Prices::LITE_PRICE).wont_be_nil
|
537
|
+
end
|
538
|
+
|
539
|
+
it 'is accessible via collection' do
|
540
|
+
_(Stripe::Prices.all).must_include Stripe::Prices::LITE_PRICE
|
541
|
+
end
|
542
|
+
|
543
|
+
it 'is accessible via hash lookup (symbol/string agnostic)' do
|
544
|
+
_(Stripe::Prices[:lite_price]).must_equal Stripe::Prices::LITE_PRICE
|
545
|
+
_(Stripe::Prices['lite_price']).must_equal Stripe::Prices::LITE_PRICE
|
546
|
+
end
|
547
|
+
|
548
|
+
describe 'constant name validation' do
|
549
|
+
it 'should be invalid when providing a constant name that can not be used for Ruby constant' do
|
550
|
+
_(lambda {
|
551
|
+
Stripe.price "Lite price".to_sym do |price|
|
552
|
+
price.name = 'Acme as a service LITE'
|
553
|
+
price.constant_name = 'LITE PRICE'
|
554
|
+
price.unit_amount = 999
|
555
|
+
price.recurring = {
|
556
|
+
interval: 'month'
|
557
|
+
}
|
558
|
+
end
|
559
|
+
}).must_raise Stripe::InvalidConfigurationError
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
describe 'uploading' do
|
564
|
+
include FixtureLoader
|
565
|
+
|
566
|
+
describe 'when none exists on stripe.com' do
|
567
|
+
before do
|
568
|
+
Stripe::Price.stubs(:list).returns(Stripe::Price.construct_from(data: []))
|
569
|
+
|
570
|
+
stub_request(:get, "https://api.stripe.com/v1/prices").
|
571
|
+
with(headers: { 'Authorization'=>'Bearer XYZ',}).
|
572
|
+
to_return(status: 200, body: load_request_fixture('stripe_prices.json'))
|
573
|
+
end
|
574
|
+
|
575
|
+
it 'creates the price online' do
|
576
|
+
Stripe::Price.expects(:create).with(
|
577
|
+
:lookup_key => "Solid Gold",
|
578
|
+
:nickname => "Solid Gold",
|
579
|
+
:currency => 'usd',
|
580
|
+
:product_data => {
|
581
|
+
:name => 'Solid Gold',
|
582
|
+
:statement_descriptor => nil
|
583
|
+
},
|
584
|
+
:unit_amount => 699,
|
585
|
+
:recurring => {
|
586
|
+
:interval => 'month'
|
587
|
+
}
|
588
|
+
)
|
589
|
+
Stripe::Prices::SOLID_GOLD.put!
|
590
|
+
end
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stripe-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Lowell
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-12-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rails
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/generators/stripe/install_generator.rb
|
91
91
|
- lib/generators/templates/coupons.rb
|
92
92
|
- lib/generators/templates/plans.rb
|
93
|
+
- lib/generators/templates/prices.rb
|
93
94
|
- lib/generators/templates/products.rb
|
94
95
|
- lib/stripe-rails.rb
|
95
96
|
- lib/stripe/billing_tier.rb
|
@@ -100,6 +101,7 @@ files:
|
|
100
101
|
- lib/stripe/current_api_version.rb
|
101
102
|
- lib/stripe/engine.rb
|
102
103
|
- lib/stripe/plans.rb
|
104
|
+
- lib/stripe/prices.rb
|
103
105
|
- lib/stripe/products.rb
|
104
106
|
- lib/stripe/rails.rb
|
105
107
|
- lib/stripe/rails/tasks.rake
|
@@ -138,6 +140,7 @@ files:
|
|
138
140
|
- test/dummy/config/locales/en.yml
|
139
141
|
- test/dummy/config/routes.rb
|
140
142
|
- test/dummy/config/stripe/plans.rb
|
143
|
+
- test/dummy/config/stripe/prices.rb
|
141
144
|
- test/dummy/lib/assets/.gitkeep
|
142
145
|
- test/dummy/lib/dummy/module_with_callbacks.rb
|
143
146
|
- test/dummy/log/.gitkeep
|
@@ -153,9 +156,11 @@ files:
|
|
153
156
|
- test/fixtures/stripe_plans.json
|
154
157
|
- test/fixtures/stripe_plans_headers.json
|
155
158
|
- test/fixtures/stripe_plans_headers_2017.json
|
159
|
+
- test/fixtures/stripe_prices.json
|
156
160
|
- test/invoice.json
|
157
161
|
- test/javascript_helper_spec.rb
|
158
162
|
- test/plan_builder_spec.rb
|
163
|
+
- test/price_builder_spec.rb
|
159
164
|
- test/product_builder_spec.rb
|
160
165
|
- test/spec_helper.rb
|
161
166
|
- test/stripe_initializers_spec.rb
|
@@ -182,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
187
|
- !ruby/object:Gem::Version
|
183
188
|
version: '0'
|
184
189
|
requirements: []
|
185
|
-
rubygems_version: 3.1.
|
190
|
+
rubygems_version: 3.1.4
|
186
191
|
signing_key:
|
187
192
|
specification_version: 4
|
188
193
|
summary: A gem to integrate stripe into your rails app
|
@@ -219,6 +224,7 @@ test_files:
|
|
219
224
|
- test/dummy/config/locales/en.yml
|
220
225
|
- test/dummy/config/routes.rb
|
221
226
|
- test/dummy/config/stripe/plans.rb
|
227
|
+
- test/dummy/config/stripe/prices.rb
|
222
228
|
- test/dummy/lib/assets/.gitkeep
|
223
229
|
- test/dummy/lib/dummy/module_with_callbacks.rb
|
224
230
|
- test/dummy/log/.gitkeep
|
@@ -234,9 +240,11 @@ test_files:
|
|
234
240
|
- test/fixtures/stripe_plans.json
|
235
241
|
- test/fixtures/stripe_plans_headers.json
|
236
242
|
- test/fixtures/stripe_plans_headers_2017.json
|
243
|
+
- test/fixtures/stripe_prices.json
|
237
244
|
- test/invoice.json
|
238
245
|
- test/javascript_helper_spec.rb
|
239
246
|
- test/plan_builder_spec.rb
|
247
|
+
- test/price_builder_spec.rb
|
240
248
|
- test/product_builder_spec.rb
|
241
249
|
- test/spec_helper.rb
|
242
250
|
- test/stripe_initializers_spec.rb
|