stripe 1.7.0 → 1.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|