stripe-rails 1.8.2 → 1.10.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +45 -0
- data/Changelog.md +22 -0
- data/Gemfile +2 -2
- data/README.md +29 -9
- data/app/models/stripe/event_dispatch.rb +15 -3
- data/gemfiles/rails4.gemfile +2 -1
- data/gemfiles/rails51.gemfile +20 -0
- data/gemfiles/rails52.gemfile +20 -0
- data/lib/generators/templates/products.rb +2 -2
- data/lib/stripe/billing_tier.rb +34 -0
- data/lib/stripe/callbacks.rb +3 -0
- data/lib/stripe/engine.rb +10 -1
- data/lib/stripe/plans.rb +33 -5
- data/lib/stripe/products.rb +2 -0
- data/lib/stripe/rails.rb +1 -0
- data/lib/stripe/rails/tasks.rake +2 -2
- data/lib/stripe/rails/version.rb +1 -1
- data/test/callbacks_spec.rb +15 -15
- data/test/coupon_builder_spec.rb +4 -4
- data/test/dummy/config/stripe/plans.rb +21 -0
- data/test/dummy_apis_controller_spec.rb +1 -1
- data/test/events_controller_spec.rb +35 -3
- data/test/javascript_helper_spec.rb +12 -12
- data/test/pings_controller_spec.rb +1 -1
- data/test/plan_builder_spec.rb +112 -36
- data/test/product_builder_spec.rb +11 -11
- data/test/spec_helper.rb +2 -2
- data/test/stripe_initializers_spec.rb +33 -21
- data/test/testing_spec.rb +8 -8
- metadata +10 -7
- data/.travis.yml +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73acf591d97fe139b79c035da2794c439658693ad685e109e538c9e43d06fb8d
|
4
|
+
data.tar.gz: 18ffadcb37501896be79ee56f57c48a8a3213b9330bca42d5edc17de92f5a3ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29d167609bc9a3dd383acce2f4aaf1a833fe17158d12dfc08e87d164cd58e1da2a141009b6de127e04f8a03186e44f88f1bfffc019a93bfb45ff47545a57f77c
|
7
|
+
data.tar.gz: 72c31c0977018cdd1fe81134aef5e888c2820ae7264d1c263f90a6521dd904ea7cfe9a3c1d8e4fa0982059365ff0c311649aec807534a607d018b2d0fe74e202
|
@@ -0,0 +1,45 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
build:
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
strategy:
|
16
|
+
matrix:
|
17
|
+
ruby: [2.4.x, 2.5.x, 2.6.x, 2.7.x]
|
18
|
+
gemfile: [Gemfile, gemfiles/rails51.gemfile, gemfiles/rails52.gemfile, gemfiles/rails4.gemfile]
|
19
|
+
exclude:
|
20
|
+
- ruby: 2.7.x
|
21
|
+
gemfile: gemfiles/rails4.gemfile
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v1
|
24
|
+
- name: Set up Ruby
|
25
|
+
uses: actions/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: ${{ matrix.ruby }}
|
28
|
+
- name: Set up Code Climate
|
29
|
+
run: |
|
30
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
31
|
+
chmod +x ./cc-test-reporter
|
32
|
+
./cc-test-reporter before-build
|
33
|
+
- name: Build and Test
|
34
|
+
env:
|
35
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
36
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
37
|
+
RUBY_VERSION: ${{ matrix.ruby }}
|
38
|
+
run: |
|
39
|
+
gem uninstall bundler
|
40
|
+
gem install bundler -v 1.17.3
|
41
|
+
bundle install --jobs 4 --retry 3
|
42
|
+
bundle exec rake
|
43
|
+
if [ `basename $BUNDLE_GEMFILE` == "Gemfile" ] && [ $RUBY_VERSION == "2.7.x" ] && [ ! -z ${CC_TEST_REPORTER_ID} ] ;
|
44
|
+
then ./cc-test-reporter after-build --exit-code $? ;
|
45
|
+
fi
|
data/Changelog.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## 1.10.2 (2020-09-18)
|
4
|
+
|
5
|
+
- adds missing callback `invoice.paid`. Thanks @SyborgStudios.
|
6
|
+
|
7
|
+
## 1.10.1 (2020-05-29)
|
8
|
+
|
9
|
+
- adds missing callbacks for `payment_intent`. Thanks @klapperkopp .
|
10
|
+
|
11
|
+
## 1.10.0 (2020-03-31)
|
12
|
+
|
13
|
+
- Adds support for using multiple tiers in a plan, thanks @cpsoinos
|
14
|
+
|
15
|
+
## 1.9.1 (2019-10-28)
|
16
|
+
|
17
|
+
- Fixes issue with `rake stripe:verify` thanks @Millariel !
|
18
|
+
|
19
|
+
## 1.9.0 (2019-09-01)
|
20
|
+
|
21
|
+
- Adds support for multiple signing secrets. Thanks again @jacobcsmith !
|
22
|
+
|
1
23
|
## 1.8.2 (2019-08-31)
|
2
24
|
|
3
25
|
- adds missing callbacks for `payment_intent`, `payment_method` and `setup_intent`. Thanks @jacobcsmith !
|
data/Gemfile
CHANGED
@@ -11,12 +11,12 @@ end
|
|
11
11
|
|
12
12
|
group :test do
|
13
13
|
gem 'mocha'
|
14
|
-
gem 'simplecov', require: false
|
14
|
+
gem 'simplecov', '< 0.18', require: false
|
15
15
|
gem 'stripe-ruby-mock'
|
16
16
|
gem 'webmock'
|
17
17
|
# Required for system tests
|
18
18
|
gem 'capybara'
|
19
|
-
gem '
|
19
|
+
gem 'webdrivers'
|
20
20
|
gem 'puma'
|
21
21
|
gem 'selenium-webdriver'
|
22
22
|
end
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Stripe::Rails: A Rails Engine for use with [stripe.com](https://stripe.com)
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/stripe-rails.
|
3
|
-
[![Build Status](https://travis-ci.org/tansengming/stripe-rails.
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/stripe-rails.svg)](https://badge.fury.io/rb/stripe-rails)
|
3
|
+
[![Build Status](https://travis-ci.org/tansengming/stripe-rails.svg?branch=master)](https://travis-ci.org/tansengming/stripe-rails)
|
4
4
|
[![Code Climate](https://codeclimate.com/github/tansengming/stripe-rails/badges/gpa.svg)](https://codeclimate.com/github/tansengming/stripe-rails)
|
5
5
|
[![Test Coverage](https://codeclimate.com/github/tansengming/stripe-rails/badges/coverage.svg)](https://codeclimate.com/github/tansengming/stripe-rails/coverage)
|
6
6
|
[![Tidelift](https://tidelift.com/badges/github/tansengming/stripe-rails)](#)
|
@@ -188,6 +188,23 @@ Stripe.plan :bronze do |plan|
|
|
188
188
|
plan.product_id = 'prod_XXXXXXXXXXXXXX'
|
189
189
|
plan.amount = 999 # $9.99
|
190
190
|
plan.interval = 'month'
|
191
|
+
|
192
|
+
# Use graduated pricing tiers
|
193
|
+
# ref: https://stripe.com/docs/api/plans/object#plan_object-tiers
|
194
|
+
plan.tiers = [
|
195
|
+
{
|
196
|
+
unit_amount: 1500,
|
197
|
+
up_to: 10
|
198
|
+
},
|
199
|
+
{
|
200
|
+
unit_amount: 1000,
|
201
|
+
up_to: 'inf'
|
202
|
+
}
|
203
|
+
]
|
204
|
+
plan.tiers_mode = 'graduated'
|
205
|
+
|
206
|
+
# set the usage type to 'metered'
|
207
|
+
plan.usage_type = 'metered'
|
191
208
|
end
|
192
209
|
```
|
193
210
|
|
@@ -310,29 +327,32 @@ Your new webhook URL would then be `http://myproductionapp/payment/stripe-integr
|
|
310
327
|
### Signed Webhooks
|
311
328
|
|
312
329
|
Validation of your webhook's signature uses your webhook endpoint signing secret.
|
313
|
-
Before you can verify signatures, you need to retrieve your endpoint’s secret your
|
330
|
+
Before you can verify signatures, you need to retrieve your endpoint’s secret from your
|
314
331
|
Stripe Dashboard. Select an endpoint for which you want to obtain
|
315
332
|
the secret, then select the Click to reveal button.
|
316
333
|
|
317
334
|
```ruby
|
318
335
|
# config/application.rb
|
319
336
|
# ...
|
320
|
-
config.stripe.
|
337
|
+
config.stripe.signing_secrets = ['whsec_XXXYYYZZZ']
|
321
338
|
```
|
322
339
|
|
323
|
-
Each secret is unique to the endpoint to which it corresponds. If you use multiple
|
340
|
+
Each secret is unique to the endpoint to which it corresponds. If you use multiple endpoint,
|
324
341
|
you must obtain a secret for each one. After this setup, Stripe starts to sign each webhook
|
325
|
-
it sends to the endpoint. Because of this, we recommend setting this variable with
|
326
|
-
|
342
|
+
it sends to the endpoint. Because of this, we recommend setting this variable with environment
|
343
|
+
variables:
|
327
344
|
|
328
345
|
```sh
|
329
346
|
export STRIPE_SIGNING_SECRET=whsec_XXXYYYZZZ
|
347
|
+
export STRIPE_CONNECT_SIGNING_SECRET=whsec_AAABBBCCC
|
330
348
|
```
|
331
349
|
|
332
350
|
```ruby
|
333
|
-
config.stripe.
|
351
|
+
config.stripe.signing_secrets = [ENV.fetch('STRIPE_SIGNING_SECRET'), ENV.fetch('STRIPE_CONNECT_SIGNING_SECRET')]
|
334
352
|
```
|
335
353
|
|
354
|
+
The first secret that successfully matches for each incoming webhook will be used to verify the incoming events.
|
355
|
+
|
336
356
|
#### Testing Signed Webhooks Locally
|
337
357
|
|
338
358
|
In order to test signed webhooks, you'll need to trigger test webhooks from your Stripe dashboard,
|
@@ -351,7 +371,7 @@ as documented above:
|
|
351
371
|
```ruby
|
352
372
|
# config/application.rb
|
353
373
|
# ...
|
354
|
-
config.stripe.
|
374
|
+
config.stripe.signing_secrets = ['whsec_XXXYYYZZZ']
|
355
375
|
```
|
356
376
|
|
357
377
|
And you'll need to restart your rails server with:
|
@@ -11,15 +11,27 @@ module Stripe
|
|
11
11
|
id = request['id']
|
12
12
|
body = request.body.read
|
13
13
|
sig_header = request.headers['HTTP_STRIPE_SIGNATURE']
|
14
|
-
|
14
|
+
endpoint_secrets = ::Rails.application.config.stripe.signing_secrets
|
15
15
|
|
16
|
-
if Object.const_defined?('Stripe::Webhook') && sig_header &&
|
17
|
-
event =
|
16
|
+
if Object.const_defined?('Stripe::Webhook') && sig_header && endpoint_secrets
|
17
|
+
event = webhook_event(body, sig_header, endpoint_secrets)
|
18
18
|
else
|
19
19
|
event = Stripe::Event.retrieve(id)
|
20
20
|
end
|
21
21
|
|
22
22
|
yield event
|
23
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def webhook_event(body, sig_header, endpoint_secrets)
|
28
|
+
endpoint_secrets.each_with_index do |secret, i|
|
29
|
+
begin
|
30
|
+
return ::Stripe::Webhook.construct_event(body, sig_header, secret.to_s)
|
31
|
+
rescue ::Stripe::SignatureVerificationError
|
32
|
+
raise if i == endpoint_secrets.length - 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
24
36
|
end
|
25
37
|
end
|
data/gemfiles/rails4.gemfile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
3
|
gem 'rails', '~> 4.2'
|
4
|
+
gem 'sprockets', '< 4'
|
4
5
|
|
5
6
|
gem 'rake'
|
6
7
|
gem 'responders', '~> 2.0' # to support Rails 4.2
|
@@ -13,7 +14,7 @@ group :test do
|
|
13
14
|
gem 'webmock'
|
14
15
|
# Required for system tests
|
15
16
|
gem 'capybara'
|
16
|
-
gem '
|
17
|
+
gem 'webdrivers'
|
17
18
|
gem 'puma'
|
18
19
|
gem 'selenium-webdriver'
|
19
20
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '~> 5.1.0'
|
4
|
+
|
5
|
+
gem 'rake'
|
6
|
+
gem 'responders'
|
7
|
+
gem 'sprockets', '< 4'
|
8
|
+
gem 'stripe'
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'mocha'
|
12
|
+
gem 'simplecov', require: false
|
13
|
+
gem 'stripe-ruby-mock'
|
14
|
+
gem 'webmock'
|
15
|
+
# Required for system tests
|
16
|
+
gem 'capybara'
|
17
|
+
gem 'puma'
|
18
|
+
gem 'selenium-webdriver'
|
19
|
+
gem 'webdrivers'
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'rails', '~> 5.2.0'
|
4
|
+
|
5
|
+
gem 'rake'
|
6
|
+
gem 'responders'
|
7
|
+
gem 'sprockets', '< 4'
|
8
|
+
gem 'stripe'
|
9
|
+
|
10
|
+
group :test do
|
11
|
+
gem 'mocha'
|
12
|
+
gem 'simplecov', require: false
|
13
|
+
gem 'stripe-ruby-mock'
|
14
|
+
gem 'webmock'
|
15
|
+
# Required for system tests
|
16
|
+
gem 'capybara'
|
17
|
+
gem 'puma'
|
18
|
+
gem 'selenium-webdriver'
|
19
|
+
gem 'webdrivers'
|
20
|
+
end
|
@@ -11,9 +11,9 @@
|
|
11
11
|
# product.type = 'service'
|
12
12
|
# end
|
13
13
|
|
14
|
-
# Once you have your
|
14
|
+
# Once you have your products defined, you can run
|
15
15
|
#
|
16
16
|
# rake stripe:prepare
|
17
17
|
#
|
18
|
-
# This will export any new
|
18
|
+
# This will export any new products to stripe.com so that you can
|
19
19
|
# begin using them in your API calls.
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Stripe
|
2
|
+
module Plans
|
3
|
+
class BillingTier
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
validates_presence_of :up_to
|
7
|
+
validates_presence_of :flat_amount, if: ->(tier) { tier.unit_amount.nil? },
|
8
|
+
message: 'one of `flat_amount` or `unit_amount` must be specified!'
|
9
|
+
validates_presence_of :unit_amount, if: ->(tier) { tier.flat_amount.nil? },
|
10
|
+
message: 'one of `flat_amount` or `unit_amount` must be specified!'
|
11
|
+
validates_absence_of :flat_amount, if: ->(tier) { tier.unit_amount.present? },
|
12
|
+
message: 'only one of `flat_amount` or `unit_amount` should be specified!'
|
13
|
+
validates_absence_of :unit_amount, if: ->(tier) { tier.flat_amount.present? },
|
14
|
+
message: 'only one of `flat_amount` or `unit_amount` should be specified!'
|
15
|
+
|
16
|
+
attr_accessor :up_to, :flat_amount, :unit_amount
|
17
|
+
|
18
|
+
def initialize(attrs)
|
19
|
+
@up_to = attrs[:up_to]
|
20
|
+
@flat_amount = attrs[:flat_amount]
|
21
|
+
@unit_amount = attrs[:unit_amount]
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
{
|
26
|
+
up_to: up_to,
|
27
|
+
flat_amount: flat_amount,
|
28
|
+
unit_amount: unit_amount
|
29
|
+
}.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/stripe/callbacks.rb
CHANGED
@@ -47,6 +47,7 @@ module Stripe
|
|
47
47
|
callback 'invoice.created'
|
48
48
|
callback 'invoice.finalized'
|
49
49
|
callback 'invoice.marked_uncollectible'
|
50
|
+
callback 'invoice.paid'
|
50
51
|
callback 'invoice.payment_action_required'
|
51
52
|
callback 'invoice.payment_failed'
|
52
53
|
callback 'invoice.payment_succeeded'
|
@@ -63,8 +64,10 @@ module Stripe
|
|
63
64
|
callback 'order.updated'
|
64
65
|
callback 'order_return.created'
|
65
66
|
callback 'payment_intent.amount_capturable_updated'
|
67
|
+
callback 'payment_intent.canceled'
|
66
68
|
callback 'payment_intent.created'
|
67
69
|
callback 'payment_intent.payment_failed'
|
70
|
+
callback 'payment_intent.processing'
|
68
71
|
callback 'payment_intent.succeeded'
|
69
72
|
callback 'payment_method.attached'
|
70
73
|
callback 'payment_method.card_automatically_updated'
|
data/lib/stripe/engine.rb
CHANGED
@@ -8,7 +8,16 @@ module Stripe
|
|
8
8
|
attr_accessor :testing
|
9
9
|
end
|
10
10
|
|
11
|
-
stripe_config = config.stripe = Struct.new(:api_base, :api_version, :secret_key, :verify_ssl_certs, :signing_secret, :publishable_key, :endpoint, :debug_js, :auto_mount, :eager_load, :open_timeout, :read_timeout)
|
11
|
+
stripe_config = config.stripe = Struct.new(:api_base, :api_version, :secret_key, :verify_ssl_certs, :signing_secret, :signing_secrets, :publishable_key, :endpoint, :debug_js, :auto_mount, :eager_load, :open_timeout, :read_timeout) do
|
12
|
+
# for backwards compatibility treat signing_secret as an alias for signing_secrets
|
13
|
+
def signing_secret=(value)
|
14
|
+
self.signing_secrets = Array(value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def signing_secret
|
18
|
+
self.signing_secrets && self.signing_secrets.first
|
19
|
+
end
|
20
|
+
end.new
|
12
21
|
|
13
22
|
def stripe_config.api_key=(key)
|
14
23
|
warn "[DEPRECATION] to align with stripe nomenclature, stripe.api_key has been renamed to config.stripe.secret_key"
|
data/lib/stripe/plans.rb
CHANGED
@@ -12,16 +12,20 @@ module Stripe
|
|
12
12
|
:interval,
|
13
13
|
:interval_count,
|
14
14
|
:metadata,
|
15
|
-
:name,
|
15
|
+
:name,
|
16
16
|
:nickname,
|
17
17
|
:product_id,
|
18
18
|
:statement_descriptor,
|
19
|
+
:tiers,
|
19
20
|
:tiers_mode,
|
21
|
+
:transform_usage,
|
20
22
|
:trial_period_days,
|
21
23
|
:usage_type
|
22
24
|
|
23
|
-
validates_presence_of :id, :
|
24
|
-
|
25
|
+
validates_presence_of :id, :currency
|
26
|
+
validates_presence_of :amount, unless: ->(p) { p.billing_scheme == 'tiered' }
|
27
|
+
validates_absence_of :transform_usage, if: ->(p) { p.billing_scheme == 'tiered' }
|
28
|
+
validates_presence_of :tiers_mode, if: ->(p) { p.billing_scheme == 'tiered' }
|
25
29
|
validates_inclusion_of :interval,
|
26
30
|
in: %w(day week month year),
|
27
31
|
message: "'%{value}' is not one of 'day', 'week', 'month' or 'year'"
|
@@ -38,6 +42,11 @@ module Stripe
|
|
38
42
|
validate :aggregate_usage_must_be_metered, if: ->(p) { p.aggregate_usage.present? }
|
39
43
|
validate :valid_constant_name, unless: ->(p) { p.constant_name.nil? }
|
40
44
|
|
45
|
+
# validations for when using tiered billing
|
46
|
+
validate :tiers_must_be_array, if: ->(p) { p.tiers.present? }
|
47
|
+
validate :billing_scheme_must_be_tiered, if: ->(p) { p.tiers.present? }
|
48
|
+
validate :validate_tiers, if: ->(p) { p.billing_scheme == 'tiered' }
|
49
|
+
|
41
50
|
def initialize(*args)
|
42
51
|
super(*args)
|
43
52
|
@currency = 'usd'
|
@@ -54,6 +63,22 @@ module Stripe
|
|
54
63
|
errors.add(:base, 'must have a product_id or a name') unless (@product_id.present? ^ @name.present?)
|
55
64
|
end
|
56
65
|
|
66
|
+
def billing_scheme_must_be_tiered
|
67
|
+
errors.add(:billing_scheme, 'must be set to `tiered` when specifying `tiers`') unless billing_scheme == 'tiered'
|
68
|
+
end
|
69
|
+
|
70
|
+
def tiers_must_be_array
|
71
|
+
errors.add(:tiers, 'must be an Array') unless tiers.is_a?(Array)
|
72
|
+
end
|
73
|
+
|
74
|
+
def billing_tiers
|
75
|
+
@billing_tiers = tiers.map { |t| Stripe::Plans::BillingTier.new(t) } if tiers
|
76
|
+
end
|
77
|
+
|
78
|
+
def validate_tiers
|
79
|
+
billing_tiers.all?(&:valid?)
|
80
|
+
end
|
81
|
+
|
57
82
|
module ConstTester; end
|
58
83
|
def valid_constant_name
|
59
84
|
ConstTester.const_set(constant_name.to_s.upcase, constant_name)
|
@@ -82,8 +107,11 @@ module Stripe
|
|
82
107
|
usage_type: usage_type,
|
83
108
|
aggregate_usage: aggregate_usage,
|
84
109
|
billing_scheme: billing_scheme,
|
85
|
-
nickname: nickname
|
86
|
-
|
110
|
+
nickname: nickname,
|
111
|
+
tiers: tiers ? tiers.map(&:to_h) : nil,
|
112
|
+
tiers_mode: tiers_mode,
|
113
|
+
transform_usage: transform_usage
|
114
|
+
}.compact
|
87
115
|
end
|
88
116
|
|
89
117
|
def product_options
|
data/lib/stripe/products.rb
CHANGED
@@ -11,6 +11,7 @@ module Stripe
|
|
11
11
|
:caption,
|
12
12
|
:metadata,
|
13
13
|
:shippable,
|
14
|
+
:unit_label,
|
14
15
|
:url,
|
15
16
|
:statement_descriptor
|
16
17
|
|
@@ -42,6 +43,7 @@ module Stripe
|
|
42
43
|
caption: caption,
|
43
44
|
metadata: metadata,
|
44
45
|
shippable: shippable,
|
46
|
+
unit_label: unit_label,
|
45
47
|
url: url,
|
46
48
|
statement_descriptor: statement_descriptor
|
47
49
|
}
|