stripe 1.7.0 → 1.7.1
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.
- data/.gitignore +2 -0
- data/.travis.yml +8 -0
- data/CONTRIBUTORS +3 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +34 -0
- data/History.txt +68 -0
- data/LICENSE +21 -0
- data/README.rdoc +28 -0
- data/Rakefile +9 -0
- data/VERSION +1 -0
- data/gemfiles/default-with-activesupport.gemfile +3 -0
- data/gemfiles/default-with-activesupport.gemfile.lock +39 -0
- data/gemfiles/json.gemfile +4 -0
- data/gemfiles/json.gemfile.lock +41 -0
- data/gemfiles/yajl.gemfile +4 -0
- data/gemfiles/yajl.gemfile.lock +41 -0
- data/lib/stripe.rb +62 -500
- data/lib/stripe/account.rb +4 -0
- data/lib/stripe/api_operations/create.rb +16 -0
- data/lib/stripe/api_operations/delete.rb +11 -0
- data/lib/stripe/api_operations/list.rb +16 -0
- data/lib/stripe/api_operations/update.rb +15 -0
- data/lib/stripe/api_resource.rb +33 -0
- data/lib/stripe/charge.rb +29 -0
- data/lib/stripe/coupon.rb +7 -0
- data/lib/stripe/customer.rb +51 -0
- data/lib/stripe/errors/api_connection_error.rb +4 -0
- data/lib/stripe/errors/api_error.rb +4 -0
- data/lib/stripe/errors/authentication_error.rb +4 -0
- data/lib/stripe/errors/card_error.rb +11 -0
- data/lib/stripe/errors/invalid_request_error.rb +10 -0
- data/lib/stripe/errors/stripe_error.rb +20 -0
- data/lib/stripe/event.rb +5 -0
- data/lib/stripe/invoice.rb +16 -0
- data/lib/stripe/invoice_item.rb +8 -0
- data/lib/stripe/json.rb +21 -0
- data/lib/stripe/plan.rb +8 -0
- data/lib/stripe/singleton_api_resource.rb +20 -0
- data/lib/stripe/stripe_object.rb +150 -0
- data/lib/stripe/token.rb +5 -0
- data/lib/stripe/transfer.rb +16 -0
- data/lib/stripe/util.rb +103 -0
- data/lib/stripe/version.rb +1 -1
- data/stripe.gemspec +28 -0
- data/test/test_helper.rb +175 -0
- data/test/test_stripe.rb +472 -0
- data/test/test_stripe_with_active_support.rb +3 -0
- metadata +54 -7
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CONTRIBUTORS
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stripe (1.7.1)
|
5
|
+
multi_json (~> 1.1)
|
6
|
+
rest-client (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
metaclass (0.0.1)
|
12
|
+
mime-types (1.19)
|
13
|
+
mocha (0.11.3)
|
14
|
+
metaclass (~> 0.0.1)
|
15
|
+
multi_json (1.3.6)
|
16
|
+
rake (0.9.2.2)
|
17
|
+
rest-client (1.6.7)
|
18
|
+
mime-types (>= 1.16)
|
19
|
+
shoulda (3.0.1)
|
20
|
+
shoulda-context (~> 1.0.0)
|
21
|
+
shoulda-matchers (~> 1.0.0)
|
22
|
+
shoulda-context (1.0.0)
|
23
|
+
shoulda-matchers (1.0.0)
|
24
|
+
test-unit (2.4.8)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
mocha
|
31
|
+
rake
|
32
|
+
shoulda
|
33
|
+
stripe!
|
34
|
+
test-unit
|
data/History.txt
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
=== 1.7.1 2012-08-15
|
2
|
+
|
3
|
+
* Add new Account API resource
|
4
|
+
|
5
|
+
=== 1.7.0 2012-05-17
|
6
|
+
|
7
|
+
* 3 major enhancements:
|
8
|
+
* Switch from vendored stripe-json to multi_json for all JSON
|
9
|
+
parsing and rendering. This should not impact programmatic usage
|
10
|
+
of the library, but may cause small rendering differences from,
|
11
|
+
e.g., StripeObject#inspect (github issue #22)
|
12
|
+
* Add new delete_discount method to Customer objects
|
13
|
+
* Add new Transfer API resource
|
14
|
+
|
15
|
+
* 2 minor enhancements:
|
16
|
+
* Switch from HTTP Basic auth to Bearer auth (Note: Stripe will
|
17
|
+
support Basic auth for the indefinite future, but recommends
|
18
|
+
Bearer auth when possible going forward)
|
19
|
+
* Numerous test suite improvements
|
20
|
+
|
21
|
+
=== 1.6.3 2012-03-22
|
22
|
+
|
23
|
+
* 1 bugfix:
|
24
|
+
* Encode GET query strings ourselves instead of using rest-client to
|
25
|
+
work around a bug
|
26
|
+
|
27
|
+
=== 1.6.2 2012-02-24
|
28
|
+
|
29
|
+
* 1 bugfix:
|
30
|
+
* Correct argument handling in StripeObject#as_json
|
31
|
+
|
32
|
+
=== 1.6.1 2012-02-22
|
33
|
+
|
34
|
+
* 1 bugfix:
|
35
|
+
* Fix StripeObject#inspect when ActiveSupport 3.0 is loaded
|
36
|
+
|
37
|
+
=== 1.6.0 2012-02-01
|
38
|
+
* A whole bunch of releases between 1.5.0 and 1.6.0, but few changes, mainly the addition of:
|
39
|
+
- plans
|
40
|
+
- coupons
|
41
|
+
- events
|
42
|
+
- tokens
|
43
|
+
* 1.6.0 also contains a new inspect/to_string implementation
|
44
|
+
|
45
|
+
=== 1.5.0 2011-05-09
|
46
|
+
|
47
|
+
* 1 major enhancement:
|
48
|
+
* Update for new RESTful API
|
49
|
+
|
50
|
+
=== 1.3.4 2011-01-07
|
51
|
+
|
52
|
+
* 1 major enhancement:
|
53
|
+
* Rename to Stripe
|
54
|
+
|
55
|
+
=== 1.2 2010-06-06
|
56
|
+
|
57
|
+
* 1 major enhancement:
|
58
|
+
* Support for the set_customer_subscription and delete_customer API methods
|
59
|
+
|
60
|
+
=== 1.1 2010-03-14
|
61
|
+
|
62
|
+
* 1 major enhancement:
|
63
|
+
* Support for recurring billing
|
64
|
+
|
65
|
+
=== 1.0 2010-01-05
|
66
|
+
|
67
|
+
* 1 major enhancement:
|
68
|
+
* Initial release
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011- Stripe, Inc. (https://stripe.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
= Stripe Ruby bindings
|
2
|
+
|
3
|
+
== Installation
|
4
|
+
|
5
|
+
You don't need this source code unless you want to modify the gem. If
|
6
|
+
you just want to use the Stripe Ruby bindings, you should run:
|
7
|
+
|
8
|
+
sudo gem install --source https://code.stripe.com stripe
|
9
|
+
|
10
|
+
If you want to build the gem from source:
|
11
|
+
|
12
|
+
sudo gem build stripe.gemspec
|
13
|
+
|
14
|
+
== Requirements
|
15
|
+
|
16
|
+
* Ruby 1.8.7 or above. (Ruby 1.8.6 may work if you load
|
17
|
+
ActiveSupport.)
|
18
|
+
* rest-client, multi_json
|
19
|
+
|
20
|
+
== Mirrors
|
21
|
+
|
22
|
+
The stripe gem is mirrored on Rubygems, so you should be able to
|
23
|
+
install it via <tt>gem install stripe</tt> if desired. We recommend using
|
24
|
+
the https://code.stripe.com mirror so all code is fetched over SSL.
|
25
|
+
|
26
|
+
== Development
|
27
|
+
|
28
|
+
Test cases can be run with: `bundle exec rake test`
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.7.1
|
@@ -0,0 +1,39 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /home/evan/src/stripe-ruby
|
3
|
+
specs:
|
4
|
+
stripe (1.7.0)
|
5
|
+
multi_json (~> 1.1)
|
6
|
+
rest-client (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.3)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
i18n (0.6.0)
|
15
|
+
metaclass (0.0.1)
|
16
|
+
mime-types (1.18)
|
17
|
+
mocha (0.11.4)
|
18
|
+
metaclass (~> 0.0.1)
|
19
|
+
multi_json (1.3.4)
|
20
|
+
rake (0.9.2.2)
|
21
|
+
rest-client (1.6.7)
|
22
|
+
mime-types (>= 1.16)
|
23
|
+
shoulda (3.0.1)
|
24
|
+
shoulda-context (~> 1.0.0)
|
25
|
+
shoulda-matchers (~> 1.0.0)
|
26
|
+
shoulda-context (1.0.0)
|
27
|
+
shoulda-matchers (1.0.0)
|
28
|
+
test-unit (2.4.8)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
activesupport
|
35
|
+
mocha
|
36
|
+
rake
|
37
|
+
shoulda
|
38
|
+
stripe!
|
39
|
+
test-unit
|
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /home/evan/src/stripe-ruby
|
3
|
+
specs:
|
4
|
+
stripe (1.7.0)
|
5
|
+
multi_json (~> 1.1)
|
6
|
+
rest-client (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.3)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
i18n (0.6.0)
|
15
|
+
json (1.7.0)
|
16
|
+
metaclass (0.0.1)
|
17
|
+
mime-types (1.18)
|
18
|
+
mocha (0.11.3)
|
19
|
+
metaclass (~> 0.0.1)
|
20
|
+
multi_json (1.3.4)
|
21
|
+
rake (0.9.2.2)
|
22
|
+
rest-client (1.6.7)
|
23
|
+
mime-types (>= 1.16)
|
24
|
+
shoulda (3.0.1)
|
25
|
+
shoulda-context (~> 1.0.0)
|
26
|
+
shoulda-matchers (~> 1.0.0)
|
27
|
+
shoulda-context (1.0.0)
|
28
|
+
shoulda-matchers (1.0.0)
|
29
|
+
test-unit (2.4.8)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
activesupport
|
36
|
+
json
|
37
|
+
mocha
|
38
|
+
rake
|
39
|
+
shoulda
|
40
|
+
stripe!
|
41
|
+
test-unit
|
@@ -0,0 +1,41 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /home/evan/src/stripe-ruby
|
3
|
+
specs:
|
4
|
+
stripe (1.7.0)
|
5
|
+
multi_json (~> 1.1)
|
6
|
+
rest-client (~> 1.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (3.2.3)
|
12
|
+
i18n (~> 0.6)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
i18n (0.6.0)
|
15
|
+
metaclass (0.0.1)
|
16
|
+
mime-types (1.18)
|
17
|
+
mocha (0.11.3)
|
18
|
+
metaclass (~> 0.0.1)
|
19
|
+
multi_json (1.3.4)
|
20
|
+
rake (0.9.2.2)
|
21
|
+
rest-client (1.6.7)
|
22
|
+
mime-types (>= 1.16)
|
23
|
+
shoulda (3.0.1)
|
24
|
+
shoulda-context (~> 1.0.0)
|
25
|
+
shoulda-matchers (~> 1.0.0)
|
26
|
+
shoulda-context (1.0.0)
|
27
|
+
shoulda-matchers (1.0.0)
|
28
|
+
test-unit (2.4.8)
|
29
|
+
yajl-ruby (1.1.0)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
activesupport
|
36
|
+
mocha
|
37
|
+
rake
|
38
|
+
shoulda
|
39
|
+
stripe!
|
40
|
+
test-unit
|
41
|
+
yajl-ruby
|
data/lib/stripe.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
# API spec at http://stripe.com/api/spec
|
3
3
|
require 'cgi'
|
4
4
|
require 'set'
|
5
|
-
|
6
5
|
require 'rubygems'
|
7
6
|
require 'openssl'
|
8
7
|
|
@@ -10,7 +9,39 @@ gem 'rest-client', '~> 1.4'
|
|
10
9
|
require 'rest_client'
|
11
10
|
require 'multi_json'
|
12
11
|
|
13
|
-
|
12
|
+
# Version
|
13
|
+
require 'stripe/version'
|
14
|
+
|
15
|
+
# API operations
|
16
|
+
require 'stripe/api_operations/create'
|
17
|
+
require 'stripe/api_operations/update'
|
18
|
+
require 'stripe/api_operations/delete'
|
19
|
+
require 'stripe/api_operations/list'
|
20
|
+
|
21
|
+
# Resources
|
22
|
+
require 'stripe/util'
|
23
|
+
require 'stripe/json'
|
24
|
+
require 'stripe/stripe_object'
|
25
|
+
require 'stripe/api_resource'
|
26
|
+
require 'stripe/singleton_api_resource'
|
27
|
+
require 'stripe/account'
|
28
|
+
require 'stripe/customer'
|
29
|
+
require 'stripe/invoice'
|
30
|
+
require 'stripe/invoice_item'
|
31
|
+
require 'stripe/charge'
|
32
|
+
require 'stripe/plan'
|
33
|
+
require 'stripe/coupon'
|
34
|
+
require 'stripe/token'
|
35
|
+
require 'stripe/event'
|
36
|
+
require 'stripe/transfer'
|
37
|
+
|
38
|
+
# Errors
|
39
|
+
require 'stripe/errors/stripe_error'
|
40
|
+
require 'stripe/errors/api_error'
|
41
|
+
require 'stripe/errors/api_connection_error'
|
42
|
+
require 'stripe/errors/card_error'
|
43
|
+
require 'stripe/errors/invalid_request_error'
|
44
|
+
require 'stripe/errors/authentication_error'
|
14
45
|
|
15
46
|
module Stripe
|
16
47
|
@@ssl_bundle_path = File.join(File.dirname(__FILE__), 'data/ca-certificates.crt')
|
@@ -18,513 +49,33 @@ module Stripe
|
|
18
49
|
@@api_base = 'https://api.stripe.com/v1'
|
19
50
|
@@verify_ssl_certs = true
|
20
51
|
|
21
|
-
|
22
|
-
|
23
|
-
case h
|
24
|
-
when APIResource
|
25
|
-
h.id
|
26
|
-
when Hash
|
27
|
-
res = {}
|
28
|
-
h.each { |k, v| res[k] = objects_to_ids(v) unless v.nil? }
|
29
|
-
res
|
30
|
-
when Array
|
31
|
-
h.map { |v| objects_to_ids(v) }
|
32
|
-
else
|
33
|
-
h
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.convert_to_stripe_object(resp, api_key)
|
38
|
-
types = {
|
39
|
-
'charge' => Charge,
|
40
|
-
'customer' => Customer,
|
41
|
-
'invoiceitem' => InvoiceItem,
|
42
|
-
'invoice' => Invoice,
|
43
|
-
'plan' => Plan,
|
44
|
-
'coupon' => Coupon,
|
45
|
-
'event' => Event,
|
46
|
-
'transfer' => Transfer
|
47
|
-
}
|
48
|
-
case resp
|
49
|
-
when Array
|
50
|
-
resp.map { |i| convert_to_stripe_object(i, api_key) }
|
51
|
-
when Hash
|
52
|
-
# Try converting to a known object class. If none available, fall back to generic APIResource
|
53
|
-
if klass_name = resp[:object]
|
54
|
-
klass = types[klass_name]
|
55
|
-
end
|
56
|
-
klass ||= StripeObject
|
57
|
-
klass.construct_from(resp, api_key)
|
58
|
-
else
|
59
|
-
resp
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.file_readable(file)
|
64
|
-
begin
|
65
|
-
File.open(file) { |f| }
|
66
|
-
rescue
|
67
|
-
false
|
68
|
-
else
|
69
|
-
true
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.symbolize_names(object)
|
74
|
-
case object
|
75
|
-
when Hash
|
76
|
-
new = {}
|
77
|
-
object.each do |key, value|
|
78
|
-
key = (key.to_sym rescue key) || key
|
79
|
-
new[key] = symbolize_names(value)
|
80
|
-
end
|
81
|
-
new
|
82
|
-
when Array
|
83
|
-
object.map { |value| symbolize_names(value) }
|
84
|
-
else
|
85
|
-
object
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.encode_key(key)
|
90
|
-
URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.flatten_params(params, parent_key = nil)
|
94
|
-
result = []
|
95
|
-
params.each do |key, value|
|
96
|
-
calculated_key = parent_key ? "#{parent_key}[#{encode_key(key)}]" : encode_key(key)
|
97
|
-
if value.is_a? Hash
|
98
|
-
result += flatten_params(value, calculated_key)
|
99
|
-
elsif value.is_a? Array
|
100
|
-
result += flatten_params_array(value, calculated_key)
|
101
|
-
else
|
102
|
-
result << [calculated_key, value]
|
103
|
-
end
|
104
|
-
end
|
105
|
-
result
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.flatten_params_array value, calculated_key
|
109
|
-
result = []
|
110
|
-
value.each do |elem|
|
111
|
-
if elem.is_a? Hash
|
112
|
-
result += flatten_params(elem, calculated_key)
|
113
|
-
elsif elem.is_a? Array
|
114
|
-
result += flatten_params_array(elem, calculated_key)
|
115
|
-
else
|
116
|
-
result << ["#{calculated_key}[]", elem]
|
117
|
-
end
|
118
|
-
end
|
119
|
-
result
|
120
|
-
end
|
52
|
+
def self.api_url(url='')
|
53
|
+
@@api_base + url
|
121
54
|
end
|
122
55
|
|
123
|
-
|
124
|
-
|
125
|
-
def self.dump(*args)
|
126
|
-
MultiJson.dump(*args)
|
127
|
-
end
|
128
|
-
def self.load(*args)
|
129
|
-
MultiJson.load(*args)
|
130
|
-
end
|
131
|
-
else
|
132
|
-
def self.dump(*args)
|
133
|
-
MultiJson.encode(*args)
|
134
|
-
end
|
135
|
-
def self.load(*args)
|
136
|
-
MultiJson.decode(*args)
|
137
|
-
end
|
138
|
-
end
|
56
|
+
def self.api_key=(api_key)
|
57
|
+
@@api_key = api_key
|
139
58
|
end
|
140
59
|
|
141
|
-
|
142
|
-
|
143
|
-
module ClassMethods
|
144
|
-
def create(params={}, api_key=nil)
|
145
|
-
response, api_key = Stripe.request(:post, self.url, api_key, params)
|
146
|
-
Util.convert_to_stripe_object(response, api_key)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
def self.included(base)
|
150
|
-
base.extend(ClassMethods)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
module Update
|
155
|
-
def save
|
156
|
-
if @unsaved_values.length > 0
|
157
|
-
values = {}
|
158
|
-
@unsaved_values.each { |k| values[k] = @values[k] }
|
159
|
-
response, api_key = Stripe.request(:post, url, @api_key, values)
|
160
|
-
refresh_from(response, api_key)
|
161
|
-
end
|
162
|
-
self
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
module Delete
|
167
|
-
def delete
|
168
|
-
response, api_key = Stripe.request(:delete, url, @api_key)
|
169
|
-
refresh_from(response, api_key)
|
170
|
-
self
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
module List
|
175
|
-
module ClassMethods
|
176
|
-
def all(filters={}, api_key=nil)
|
177
|
-
response, api_key = Stripe.request(:get, url, api_key, filters)
|
178
|
-
Util.convert_to_stripe_object(response, api_key)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def self.included(base)
|
183
|
-
base.extend(ClassMethods)
|
184
|
-
end
|
185
|
-
end
|
60
|
+
def self.api_key
|
61
|
+
@@api_key
|
186
62
|
end
|
187
63
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
attr_accessor :api_key
|
192
|
-
@@permanent_attributes = Set.new([:api_key])
|
193
|
-
|
194
|
-
# The default :id method is deprecated and isn't useful to us
|
195
|
-
if method_defined?(:id)
|
196
|
-
undef :id
|
197
|
-
end
|
198
|
-
|
199
|
-
def initialize(id=nil, api_key=nil)
|
200
|
-
@api_key = api_key
|
201
|
-
@values = {}
|
202
|
-
# This really belongs in APIResource, but not putting it there allows us
|
203
|
-
# to have a unified inspect method
|
204
|
-
@unsaved_values = Set.new
|
205
|
-
@transient_values = Set.new
|
206
|
-
self.id = id if id
|
207
|
-
end
|
208
|
-
|
209
|
-
def self.construct_from(values, api_key=nil)
|
210
|
-
obj = self.new(values[:id], api_key)
|
211
|
-
obj.refresh_from(values, api_key)
|
212
|
-
obj
|
213
|
-
end
|
214
|
-
|
215
|
-
def to_s(*args); Stripe::JSON.dump(@values, :pretty => true); end
|
216
|
-
|
217
|
-
def inspect()
|
218
|
-
id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
|
219
|
-
"#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + Stripe::JSON.dump(@values, :pretty => true)
|
220
|
-
end
|
221
|
-
|
222
|
-
def refresh_from(values, api_key, partial=false)
|
223
|
-
@api_key = api_key
|
224
|
-
|
225
|
-
removed = partial ? Set.new : Set.new(@values.keys - values.keys)
|
226
|
-
added = Set.new(values.keys - @values.keys)
|
227
|
-
# Wipe old state before setting new. This is useful for e.g. updating a
|
228
|
-
# customer, where there is no persistent card parameter. Mark those values
|
229
|
-
# which don't persist as transient
|
230
|
-
|
231
|
-
instance_eval do
|
232
|
-
remove_accessors(removed)
|
233
|
-
add_accessors(added)
|
234
|
-
end
|
235
|
-
removed.each do |k|
|
236
|
-
@values.delete(k)
|
237
|
-
@transient_values.add(k)
|
238
|
-
@unsaved_values.delete(k)
|
239
|
-
end
|
240
|
-
values.each do |k, v|
|
241
|
-
@values[k] = Util.convert_to_stripe_object(v, api_key)
|
242
|
-
@transient_values.delete(k)
|
243
|
-
@unsaved_values.delete(k)
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def [](k)
|
248
|
-
k = k.to_sym if k.kind_of?(String)
|
249
|
-
@values[k]
|
250
|
-
end
|
251
|
-
def []=(k, v)
|
252
|
-
send(:"#{k}=", v)
|
253
|
-
end
|
254
|
-
def keys; @values.keys; end
|
255
|
-
def values; @values.values; end
|
256
|
-
def to_json(*a); Stripe::JSON.dump(@values); end
|
257
|
-
def as_json(*a); @values.as_json(*a); end
|
258
|
-
def to_hash; @values; end
|
259
|
-
def each(&blk); @values.each(&blk); end
|
260
|
-
|
261
|
-
protected
|
262
|
-
|
263
|
-
def metaclass
|
264
|
-
class << self; self; end
|
265
|
-
end
|
266
|
-
|
267
|
-
def remove_accessors(keys)
|
268
|
-
metaclass.instance_eval do
|
269
|
-
keys.each do |k|
|
270
|
-
next if @@permanent_attributes.include?(k)
|
271
|
-
k_eq = :"#{k}="
|
272
|
-
remove_method(k) if method_defined?(k)
|
273
|
-
remove_method(k_eq) if method_defined?(k_eq)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def add_accessors(keys)
|
279
|
-
metaclass.instance_eval do
|
280
|
-
keys.each do |k|
|
281
|
-
next if @@permanent_attributes.include?(k)
|
282
|
-
k_eq = :"#{k}="
|
283
|
-
define_method(k) { @values[k] }
|
284
|
-
define_method(k_eq) do |v|
|
285
|
-
@values[k] = v
|
286
|
-
@unsaved_values.add(k)
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
def method_missing(name, *args)
|
293
|
-
# TODO: only allow setting in updateable classes.
|
294
|
-
if name.to_s.end_with?('=')
|
295
|
-
attr = name.to_s[0...-1].to_sym
|
296
|
-
@values[attr] = args[0]
|
297
|
-
@unsaved_values.add(attr)
|
298
|
-
add_accessors([attr])
|
299
|
-
return
|
300
|
-
else
|
301
|
-
return @values[name] if @values.has_key?(name)
|
302
|
-
end
|
303
|
-
|
304
|
-
begin
|
305
|
-
super
|
306
|
-
rescue NoMethodError => e
|
307
|
-
if @transient_values.include?(name)
|
308
|
-
raise NoMethodError.new(e.message + ". HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: #{@values.keys.join(', ')}")
|
309
|
-
else
|
310
|
-
raise
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
64
|
+
def self.api_base=(api_base)
|
65
|
+
@@api_base = api_base
|
314
66
|
end
|
315
67
|
|
316
|
-
|
317
|
-
|
318
|
-
if self == APIResource
|
319
|
-
raise NotImplementedError.new("APIResource is an abstract class. You should perform actions on its subclasses (Charge, Customer, etc.)")
|
320
|
-
end
|
321
|
-
shortname = self.name.split('::')[-1]
|
322
|
-
"/#{CGI.escape(shortname.downcase)}s"
|
323
|
-
end
|
324
|
-
def url
|
325
|
-
id = self['id']
|
326
|
-
raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", 'id') unless id
|
327
|
-
"#{self.class.url}/#{CGI.escape(id)}"
|
328
|
-
end
|
329
|
-
|
330
|
-
def refresh
|
331
|
-
response, api_key = Stripe.request(:get, url, @api_key)
|
332
|
-
refresh_from(response, api_key)
|
333
|
-
self
|
334
|
-
end
|
335
|
-
|
336
|
-
def self.retrieve(id, api_key=nil)
|
337
|
-
instance = self.new(id, api_key)
|
338
|
-
instance.refresh
|
339
|
-
instance
|
340
|
-
end
|
341
|
-
|
342
|
-
protected
|
343
|
-
end
|
344
|
-
|
345
|
-
class Customer < APIResource
|
346
|
-
include Stripe::APIOperations::Create
|
347
|
-
include Stripe::APIOperations::Delete
|
348
|
-
include Stripe::APIOperations::Update
|
349
|
-
include Stripe::APIOperations::List
|
350
|
-
|
351
|
-
def add_invoice_item(params)
|
352
|
-
InvoiceItem.create(params.merge(:customer => id), @api_key)
|
353
|
-
end
|
354
|
-
|
355
|
-
def invoices
|
356
|
-
Invoice.all({ :customer => id }, @api_key)
|
357
|
-
end
|
358
|
-
|
359
|
-
def invoice_items
|
360
|
-
InvoiceItem.all({ :customer => id }, @api_key)
|
361
|
-
end
|
362
|
-
|
363
|
-
def charges
|
364
|
-
Charge.all({ :customer => id }, @api_key)
|
365
|
-
end
|
366
|
-
|
367
|
-
def cancel_subscription(params={})
|
368
|
-
response, api_key = Stripe.request(:delete, subscription_url, @api_key, params)
|
369
|
-
refresh_from({ :subscription => response }, api_key, true)
|
370
|
-
subscription
|
371
|
-
end
|
372
|
-
|
373
|
-
def update_subscription(params)
|
374
|
-
response, api_key = Stripe.request(:post, subscription_url, @api_key, params)
|
375
|
-
refresh_from({ :subscription => response }, api_key, true)
|
376
|
-
subscription
|
377
|
-
end
|
378
|
-
|
379
|
-
def delete_discount
|
380
|
-
Stripe.request(:delete, discount_url, @api_key)
|
381
|
-
refresh_from({ :discount => nil }, api_key, true)
|
382
|
-
end
|
383
|
-
|
384
|
-
private
|
385
|
-
|
386
|
-
def discount_url
|
387
|
-
url + '/discount'
|
388
|
-
end
|
389
|
-
|
390
|
-
def subscription_url
|
391
|
-
url + '/subscription'
|
392
|
-
end
|
393
|
-
end
|
394
|
-
|
395
|
-
class Invoice < APIResource
|
396
|
-
include Stripe::APIOperations::List
|
397
|
-
|
398
|
-
def self.upcoming(params)
|
399
|
-
response, api_key = Stripe.request(:get, upcoming_url, @api_key, params)
|
400
|
-
Util.convert_to_stripe_object(response, api_key)
|
401
|
-
end
|
402
|
-
|
403
|
-
private
|
404
|
-
|
405
|
-
def self.upcoming_url
|
406
|
-
url + '/upcoming'
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
class InvoiceItem < APIResource
|
411
|
-
include Stripe::APIOperations::List
|
412
|
-
include Stripe::APIOperations::Create
|
413
|
-
include Stripe::APIOperations::Delete
|
414
|
-
include Stripe::APIOperations::Update
|
415
|
-
end
|
416
|
-
|
417
|
-
class Charge < APIResource
|
418
|
-
include Stripe::APIOperations::List
|
419
|
-
include Stripe::APIOperations::Create
|
420
|
-
include Stripe::APIOperations::Update
|
421
|
-
|
422
|
-
def refund(params={})
|
423
|
-
response, api_key = Stripe.request(:post, refund_url, @api_key, params)
|
424
|
-
refresh_from(response, api_key)
|
425
|
-
self
|
426
|
-
end
|
427
|
-
|
428
|
-
def capture(params={})
|
429
|
-
response, api_key = Stripe.request(:post, capture_url, @api_key, params)
|
430
|
-
refresh_from(response, api_key)
|
431
|
-
self
|
432
|
-
end
|
433
|
-
|
434
|
-
private
|
435
|
-
|
436
|
-
def refund_url
|
437
|
-
url + '/refund'
|
438
|
-
end
|
439
|
-
|
440
|
-
def capture_url
|
441
|
-
url + '/capture'
|
442
|
-
end
|
443
|
-
end
|
444
|
-
|
445
|
-
class Plan < APIResource
|
446
|
-
include Stripe::APIOperations::Create
|
447
|
-
include Stripe::APIOperations::Delete
|
448
|
-
include Stripe::APIOperations::List
|
449
|
-
include Stripe::APIOperations::Update
|
450
|
-
end
|
451
|
-
|
452
|
-
class Coupon < APIResource
|
453
|
-
include Stripe::APIOperations::Create
|
454
|
-
include Stripe::APIOperations::Delete
|
455
|
-
include Stripe::APIOperations::List
|
456
|
-
end
|
457
|
-
|
458
|
-
class Token < APIResource
|
459
|
-
include Stripe::APIOperations::Create
|
460
|
-
end
|
461
|
-
|
462
|
-
class Event < APIResource
|
463
|
-
include Stripe::APIOperations::List
|
464
|
-
end
|
465
|
-
|
466
|
-
class Transfer < APIResource
|
467
|
-
include Stripe::APIOperations::List
|
468
|
-
|
469
|
-
def transactions(params={})
|
470
|
-
response, api_key = Stripe.request(:get, transactions_url, @api_key, params)
|
471
|
-
Util.convert_to_stripe_object(response, api_key)
|
472
|
-
end
|
473
|
-
|
474
|
-
private
|
475
|
-
|
476
|
-
def transactions_url
|
477
|
-
url + '/transactions'
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
class StripeError < StandardError
|
482
|
-
attr_reader :message
|
483
|
-
attr_reader :http_status
|
484
|
-
attr_reader :http_body
|
485
|
-
attr_reader :json_body
|
486
|
-
|
487
|
-
def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
|
488
|
-
@message = message
|
489
|
-
@http_status = http_status
|
490
|
-
@http_body = http_body
|
491
|
-
@json_body = json_body
|
492
|
-
end
|
493
|
-
|
494
|
-
def to_s
|
495
|
-
status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
|
496
|
-
"#{status_string}#{@message}"
|
497
|
-
end
|
68
|
+
def self.api_base
|
69
|
+
@@api_base
|
498
70
|
end
|
499
71
|
|
500
|
-
|
501
|
-
|
502
|
-
class CardError < StripeError
|
503
|
-
attr_reader :param, :code
|
504
|
-
|
505
|
-
def initialize(message, param, code, http_status=nil, http_body=nil, json_body=nil)
|
506
|
-
super(message, http_status, http_body, json_body)
|
507
|
-
@param = param
|
508
|
-
@code = code
|
509
|
-
end
|
72
|
+
def self.verify_ssl_certs=(verify)
|
73
|
+
@@verify_ssl_certs = verify
|
510
74
|
end
|
511
|
-
class InvalidRequestError < StripeError
|
512
|
-
attr_accessor :param
|
513
75
|
|
514
|
-
|
515
|
-
|
516
|
-
@param = param
|
517
|
-
end
|
76
|
+
def self.verify_ssl_certs
|
77
|
+
@@verify_ssl_certs
|
518
78
|
end
|
519
|
-
class AuthenticationError < StripeError; end
|
520
|
-
|
521
|
-
def self.api_url(url=''); @@api_base + url; end
|
522
|
-
def self.api_key=(api_key); @@api_key = api_key; end
|
523
|
-
def self.api_key; @@api_key; end
|
524
|
-
def self.api_base=(api_base); @@api_base = api_base; end
|
525
|
-
def self.api_base; @@api_base; end
|
526
|
-
def self.verify_ssl_certs=(verify); @@verify_ssl_certs = verify; end
|
527
|
-
def self.verify_ssl_certs; @@verify_ssl_certs; end
|
528
79
|
|
529
80
|
def self.request(method, url, api_key, params=nil, headers={})
|
530
81
|
api_key ||= @@api_key
|
@@ -658,10 +209,21 @@ module Stripe
|
|
658
209
|
end
|
659
210
|
end
|
660
211
|
|
661
|
-
def self.invalid_request_error(error, rcode, rbody, error_obj)
|
662
|
-
|
663
|
-
|
664
|
-
|
212
|
+
def self.invalid_request_error(error, rcode, rbody, error_obj)
|
213
|
+
InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj)
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.authentication_error(error, rcode, rbody, error_obj)
|
217
|
+
AuthenticationError.new(error[:message], rcode, rbody, error_obj)
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.card_error(error, rcode, rbody, error_obj)
|
221
|
+
CardError.new(error[:message], error[:param], error[:code], rcode, rbody, error_obj)
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.api_error(error, rcode, rbody, error_obj)
|
225
|
+
APIError.new(error[:message], rcode, rbody, error_obj)
|
226
|
+
end
|
665
227
|
|
666
228
|
def self.handle_restclient_error(e)
|
667
229
|
case e
|