boffinio 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/boffinio.gemspec +31 -0
- data/lib/boffinio/api_operations/create.rb +16 -0
- data/lib/boffinio/api_operations/delete.rb +11 -0
- data/lib/boffinio/api_operations/list.rb +16 -0
- data/lib/boffinio/api_operations/update.rb +57 -0
- data/lib/boffinio/api_resource.rb +33 -0
- data/lib/boffinio/boffinio_object.rb +190 -0
- data/lib/boffinio/customer.rb +36 -0
- data/lib/boffinio/errors/api_error.rb +4 -0
- data/lib/boffinio/errors/authentication_error.rb +4 -0
- data/lib/boffinio/errors/boffinio_error.rb +20 -0
- data/lib/boffinio/errors/invalid_request_error.rb +4 -0
- data/lib/boffinio/list_object.rb +35 -0
- data/lib/boffinio/plan.rb +7 -0
- data/lib/boffinio/subscription.rb +10 -0
- data/lib/boffinio/util.rb +87 -0
- data/lib/boffinio/version.rb +3 -0
- data/lib/boffinio.rb +229 -0
- data/test/customer/customer_test.rb +149 -0
- data/test/fixtures/all_customers.yml +62 -0
- data/test/fixtures/cancel_subscription.yml +62 -0
- data/test/fixtures/create_customer.yml +66 -0
- data/test/fixtures/create_subscription.yml +66 -0
- data/test/fixtures/customer_subscriptions.yml +62 -0
- data/test/fixtures/one_customer.yml +67 -0
- data/test/fixtures/update_customer.yml +64 -0
- data/test/fixtures/update_named_subscription.yml +64 -0
- data/test/fixtures/update_subscription.yml +66 -0
- data/test/subscription/subscription_test.rb +0 -0
- data/test/test_helper.rb +13 -0
- metadata +210 -0
data/lib/boffinio.rb
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'set'
|
3
|
+
require 'json'
|
4
|
+
#Version
|
5
|
+
require_relative "boffinio/version"
|
6
|
+
|
7
|
+
#API Operations
|
8
|
+
require_relative 'boffinio/api_operations/list'
|
9
|
+
require_relative 'boffinio/api_operations/create'
|
10
|
+
require_relative 'boffinio/api_operations/delete'
|
11
|
+
require_relative 'boffinio/api_operations/update'
|
12
|
+
|
13
|
+
#Resources
|
14
|
+
require_relative 'boffinio/util'
|
15
|
+
require_relative 'boffinio/boffinio_object'
|
16
|
+
require_relative 'boffinio/api_resource'
|
17
|
+
require_relative "boffinio/list_object"
|
18
|
+
require_relative "boffinio/customer"
|
19
|
+
require_relative "boffinio/subscription"
|
20
|
+
require_relative "boffinio/plan"
|
21
|
+
|
22
|
+
#Errors
|
23
|
+
require_relative 'boffinio/errors/boffinio_error'
|
24
|
+
require_relative 'boffinio/errors/api_error'
|
25
|
+
require_relative 'boffinio/errors/authentication_error'
|
26
|
+
require_relative 'boffinio/errors/invalid_request_error'
|
27
|
+
|
28
|
+
require 'rest-client'
|
29
|
+
|
30
|
+
module BoffinIO
|
31
|
+
|
32
|
+
@api_base = 'https://api.boffin.io'
|
33
|
+
@api_version = "v1"
|
34
|
+
|
35
|
+
class << self
|
36
|
+
attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.api_url(url='')
|
40
|
+
@api_base+url
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.request(method, url, api_key, params={}, headers={})
|
44
|
+
unless api_key ||= @api_key
|
45
|
+
raise AuthenticationError.new('No API key provided. ' +
|
46
|
+
'Set your API key using "BoffinIO.api_key = <API-KEY>". ' +
|
47
|
+
'You can generate API keys from the Boffin web interface. ')
|
48
|
+
end
|
49
|
+
|
50
|
+
if api_key =~ /\s/
|
51
|
+
raise AuthenticationError.new('Your API key is invalid, as it contains ' +
|
52
|
+
'whitespace. (HINT: You can double-check your API key from the ' +
|
53
|
+
'Boffin web interface. See https://boffion.io/api for details, or ' +
|
54
|
+
'email support@boffin.io if you have any questions.)')
|
55
|
+
end
|
56
|
+
|
57
|
+
request_opts = { :verify_ssl => false }
|
58
|
+
|
59
|
+
params = Util.objects_to_ids(params)
|
60
|
+
url = api_url(url)
|
61
|
+
|
62
|
+
case method.to_s.downcase.to_sym
|
63
|
+
when :get, :head, :delete
|
64
|
+
# Make params into GET parameters
|
65
|
+
url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
|
66
|
+
payload = nil
|
67
|
+
else
|
68
|
+
payload = uri_encode(params)
|
69
|
+
end
|
70
|
+
request_opts.update(:headers => request_headers(api_key).update(headers),
|
71
|
+
:method => method, :open_timeout => 30,
|
72
|
+
:payload => payload, :url => url, :timeout => 80)
|
73
|
+
|
74
|
+
begin
|
75
|
+
response = execute_request(request_opts)
|
76
|
+
rescue SocketError => e
|
77
|
+
handle_restclient_error(e)
|
78
|
+
rescue NoMethodError => e
|
79
|
+
# Work around RestClient bug
|
80
|
+
if e.message =~ /\WRequestFailed\W/
|
81
|
+
e = APIConnectionError.new('Unexpected HTTP response code')
|
82
|
+
handle_restclient_error(e)
|
83
|
+
else
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
rescue RestClient::ExceptionWithResponse => e
|
87
|
+
if rcode = e.http_code and rbody = e.http_body
|
88
|
+
handle_api_error(rcode, rbody)
|
89
|
+
else
|
90
|
+
handle_restclient_error(e)
|
91
|
+
end
|
92
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
93
|
+
handle_restclient_error(e)
|
94
|
+
end
|
95
|
+
|
96
|
+
[parse(response), api_key]
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.user_agent
|
100
|
+
@uname ||= get_uname
|
101
|
+
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
102
|
+
|
103
|
+
{
|
104
|
+
:bindings_version => BoffinIO::VERSION,
|
105
|
+
:lang => 'ruby',
|
106
|
+
:lang_version => lang_version,
|
107
|
+
:platform => RUBY_PLATFORM,
|
108
|
+
:publisher => 'boffinio',
|
109
|
+
:uname => @uname
|
110
|
+
}
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.get_uname
|
115
|
+
`uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
|
116
|
+
rescue Errno::ENOMEM => ex # couldn't create subprocess
|
117
|
+
"uname lookup failed"
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.request_headers(api_key)
|
121
|
+
headers = {
|
122
|
+
:user_agent => "Boffin/v1 RubyBindings/#{BoffinIO::VERSION}",
|
123
|
+
:authorization => "Token token=#{api_key}",
|
124
|
+
:content_type => 'application/x-www-form-urlencoded'
|
125
|
+
}
|
126
|
+
|
127
|
+
headers[:boffinio_version] = api_version if api_version
|
128
|
+
|
129
|
+
begin
|
130
|
+
headers.update(:x_boffinio_client_user_agent => JSON.generate(user_agent))
|
131
|
+
rescue => e
|
132
|
+
headers.update(:x_boffinio_client_raw_user_agent => user_agent.inspect,
|
133
|
+
:error => "#{e} (#{e.class})")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.uri_encode(params)
|
138
|
+
Util.flatten_params(params).
|
139
|
+
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.execute_request(opts)
|
143
|
+
RestClient::Request.execute(opts)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.parse(response)
|
147
|
+
begin
|
148
|
+
# Would use :symbolize_names => true, but apparently there is
|
149
|
+
# some library out there that makes symbolize_names not work.
|
150
|
+
response = JSON.parse(response.body)
|
151
|
+
rescue JSON::ParserError
|
152
|
+
raise general_api_error(response.code, response.body)
|
153
|
+
end
|
154
|
+
|
155
|
+
Util.symbolize_names(response)
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.handle_api_error(rcode, rbody)
|
159
|
+
begin
|
160
|
+
error_obj = JSON.parse(rbody)
|
161
|
+
error_obj = Util.symbolize_names(error_obj)
|
162
|
+
error = error_obj[:error] or raise BoffinIOError.new # escape from parsing
|
163
|
+
|
164
|
+
rescue JSON::ParserError, BoffinIOError
|
165
|
+
raise general_api_error(rcode, rbody)
|
166
|
+
end
|
167
|
+
|
168
|
+
case rcode
|
169
|
+
when 400, 404
|
170
|
+
raise invalid_request_error error, rcode, rbody, error_obj
|
171
|
+
when 401
|
172
|
+
raise authentication_error error, rcode, rbody, error_obj
|
173
|
+
else
|
174
|
+
raise api_error error, rcode, rbody, error_obj
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.invalid_request_error(error, rcode, rbody, error_obj)
|
180
|
+
InvalidRequestError.new(error[:message], error[:param], rcode,
|
181
|
+
rbody, error_obj)
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.authentication_error(error, rcode, rbody, error_obj)
|
185
|
+
AuthenticationError.new(error[:message], rcode, rbody, error_obj)
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.api_error(error, rcode, rbody, error_obj)
|
189
|
+
APIError.new(error[:message], rcode, rbody, error_obj)
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.general_api_error(rcode, rbody)
|
193
|
+
BoffinIOError.new("Invalid response object from API: #{rbody.inspect} " +
|
194
|
+
"(HTTP response code was #{rcode})", rcode, rbody)
|
195
|
+
end
|
196
|
+
|
197
|
+
def self.handle_restclient_error(e)
|
198
|
+
connection_message = "Please check your internet connection and try again. " \
|
199
|
+
"If this problem persists, you should check Boffin's service status at " \
|
200
|
+
"https://twitter.com/boffinio, or let us know at support@boffin.io."
|
201
|
+
|
202
|
+
case e
|
203
|
+
when RestClient::RequestTimeout
|
204
|
+
message = "Could not connect to Boffin (#{@api_base}). #{connection_message}"
|
205
|
+
|
206
|
+
when RestClient::ServerBrokeConnection
|
207
|
+
message = "The connection to the server (#{@api_base}) broke before the " \
|
208
|
+
"request completed. #{connection_message}"
|
209
|
+
|
210
|
+
when RestClient::SSLCertificateNotVerified
|
211
|
+
message = "Could not verify Boffin's SSL certificate. " \
|
212
|
+
"Please make sure that your network is not intercepting certificates. " \
|
213
|
+
"(Try going to https://api.boffin.com/v1 in your browser.) " \
|
214
|
+
"If this problem persists, let us know at support@boffin.io."
|
215
|
+
|
216
|
+
when SocketError
|
217
|
+
message = "Unexpected error communicating when trying to connect to Boffin. " \
|
218
|
+
"You may be seeing this message because your DNS is not working. " \
|
219
|
+
"To check, try running 'host boffin.io' from the command line."
|
220
|
+
|
221
|
+
else
|
222
|
+
message = "Unexpected error communicating with Boffin. " \
|
223
|
+
"If this problem persists, let us know at support@boffin.io."
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
raise BoffinIOError.new(message + "\n\n(Network error: #{e.message})")
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require './test/test_helper'
|
2
|
+
|
3
|
+
class BoffinIOCustomerTest < Minitest::Test
|
4
|
+
def test_exists
|
5
|
+
assert BoffinIO::Customer
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_it_gives_back_a_single_customer
|
9
|
+
VCR.use_cassette('one_customer') do
|
10
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
11
|
+
assert_equal BoffinIO::Customer, customer.class
|
12
|
+
|
13
|
+
# Check that the fields are accessible by our model
|
14
|
+
assert_equal "1398", customer.ref_id
|
15
|
+
assert_equal "Tim Williams", customer.description
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_it_gives_back_all_customers
|
20
|
+
VCR.use_cassette('all_customers') do
|
21
|
+
result = BoffinIO::Customer.all
|
22
|
+
|
23
|
+
# Make sure we got all the cars
|
24
|
+
assert_equal 11, result.count
|
25
|
+
|
26
|
+
# Make sure that the JSON was parsed
|
27
|
+
assert result.kind_of?(BoffinIO::ListObject)
|
28
|
+
customers = result.data
|
29
|
+
assert customers.first.kind_of?(BoffinIO::Customer)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_it_creates_one_customer
|
34
|
+
VCR.use_cassette('create_customer') do
|
35
|
+
customer = BoffinIO::Customer.create(
|
36
|
+
ref_id: "test1234",
|
37
|
+
description: "Tim Williams",
|
38
|
+
email: "tim@example.com"
|
39
|
+
)
|
40
|
+
|
41
|
+
# Make sure we got all the cars
|
42
|
+
assert_equal "test1234", customer.ref_id
|
43
|
+
assert_equal "Tim Williams", customer.description
|
44
|
+
assert_equal "tim@example.com", customer.email
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_it_updates_a_named_customer
|
49
|
+
VCR.use_cassette('one_customer') do
|
50
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
51
|
+
VCR.use_cassette('update_customer', :record => :new_episodes) do
|
52
|
+
customer.email="timwilliams@example.com"
|
53
|
+
result = customer.save
|
54
|
+
assert_equal "timwilliams@example.com",result.email
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_it_creates_one_subscription
|
60
|
+
VCR.use_cassette('one_customer') do
|
61
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
62
|
+
VCR.use_cassette('create_subscription') do
|
63
|
+
metadata = {:provider => "heroku"}
|
64
|
+
subscription = customer.create_subscription(
|
65
|
+
plan: "foo",
|
66
|
+
metadata: metadata,
|
67
|
+
start: Time.new(2014,1,1)
|
68
|
+
)
|
69
|
+
assert_equal BoffinIO::Subscription, subscription.class
|
70
|
+
plan = subscription.plan
|
71
|
+
assert_equal BoffinIO::Plan, plan.class
|
72
|
+
assert_equal "foo", plan.slug
|
73
|
+
assert_equal "heroku",subscription.metadata[:provider]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_it_creates_one_subscription
|
79
|
+
VCR.use_cassette('one_customer') do
|
80
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
81
|
+
VCR.use_cassette('create_subscription') do
|
82
|
+
metadata = {:provider => "heroku"}
|
83
|
+
subscription = customer.create_subscription(
|
84
|
+
plan: "foo",
|
85
|
+
metadata: metadata,
|
86
|
+
start: Time.new(2014,1,1)
|
87
|
+
)
|
88
|
+
assert_equal BoffinIO::Subscription, subscription.class
|
89
|
+
plan = subscription.plan
|
90
|
+
assert_equal BoffinIO::Plan, plan.class
|
91
|
+
assert_equal "foo", plan.slug
|
92
|
+
assert_equal "heroku",subscription.metadata[:provider]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_it_deletes_subscriptions
|
98
|
+
VCR.use_cassette('one_customer') do
|
99
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
100
|
+
VCR.use_cassette('cancel_subscription') do
|
101
|
+
subscription = customer.cancel_subscription
|
102
|
+
assert_equal BoffinIO::Subscription, subscription.class
|
103
|
+
refute_nil subscription.canceled_at
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_it_updates_subscriptions
|
109
|
+
VCR.use_cassette('one_customer') do
|
110
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
111
|
+
VCR.use_cassette('update_subscription') do
|
112
|
+
metadata = {:provider => "heroku"}
|
113
|
+
subscription = customer.update_subscription(:plan => "test", :metadata => metadata)
|
114
|
+
assert_equal BoffinIO::Subscription, subscription.class
|
115
|
+
plan = subscription.plan
|
116
|
+
assert_equal BoffinIO::Plan, plan.class
|
117
|
+
assert_equal "test", plan.slug
|
118
|
+
assert_equal "heroku",subscription.metadata[:provider]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_it_lists_subscriptions
|
124
|
+
VCR.use_cassette('one_customer') do
|
125
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
126
|
+
VCR.use_cassette('customer_subscriptions', :record => :new_episodes) do
|
127
|
+
subscriptions = customer.subscriptions.all
|
128
|
+
sub1 = subscriptions.first
|
129
|
+
assert_equal BoffinIO::Subscription, sub1.class
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_it_updates_a_named_subscription
|
135
|
+
VCR.use_cassette('one_customer') do
|
136
|
+
customer = BoffinIO::Customer.retrieve("1398")
|
137
|
+
VCR.use_cassette('customer_subscriptions', :record => :new_episodes) do
|
138
|
+
subscriptions = customer.subscriptions.all
|
139
|
+
sub1 = subscriptions.first
|
140
|
+
sub1.metadata = {:country => "gb"}
|
141
|
+
VCR.use_cassette('update_named_subscription', :record => :new_episodes) do
|
142
|
+
result = sub1.save
|
143
|
+
assert_equal "gb",result.metadata[:country]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://api.boffin-dev.io:3000/v1/customers
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*; q=0.5, application/xml"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Boffin/v1 RubyBindings/0.0.1
|
16
|
+
Authorization:
|
17
|
+
- Token token=141d246d5e0774eaab3482259516dae9
|
18
|
+
Content-Type:
|
19
|
+
- application/x-www-form-urlencoded
|
20
|
+
Stripe-Version:
|
21
|
+
- v1
|
22
|
+
X-Stripe-Client-User-Agent:
|
23
|
+
- '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
|
24
|
+
tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
|
25
|
+
x86_64 x86_64 GNU/Linux"}'
|
26
|
+
response:
|
27
|
+
status:
|
28
|
+
code: 200
|
29
|
+
message: 'OK '
|
30
|
+
headers:
|
31
|
+
X-Frame-Options:
|
32
|
+
- SAMEORIGIN
|
33
|
+
X-Xss-Protection:
|
34
|
+
- 1; mode=block
|
35
|
+
X-Content-Type-Options:
|
36
|
+
- nosniff
|
37
|
+
Content-Type:
|
38
|
+
- application/json; charset=utf-8
|
39
|
+
Etag:
|
40
|
+
- '"a81d3321ce01aa68b3fbb332e3622605"'
|
41
|
+
Cache-Control:
|
42
|
+
- max-age=0, private, must-revalidate
|
43
|
+
X-Request-Id:
|
44
|
+
- 49c89e41-ecd2-4bb6-92f5-aff6f530d2d1
|
45
|
+
X-Runtime:
|
46
|
+
- '0.298277'
|
47
|
+
Server:
|
48
|
+
- WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
|
49
|
+
Date:
|
50
|
+
- Sun, 26 Oct 2014 12:39:08 GMT
|
51
|
+
Content-Length:
|
52
|
+
- '2069'
|
53
|
+
Connection:
|
54
|
+
- Keep-Alive
|
55
|
+
Set-Cookie:
|
56
|
+
- request_method=GET; path=/
|
57
|
+
body:
|
58
|
+
encoding: UTF-8
|
59
|
+
string: '{"object":"list","url":"/v1/customers","count":11,"data":[{"object":"customer","id":"900","ref_id":"900","description":null,"email":"tim@teachmatic.com","subscriptions":{"object":"list","url":"/v1/customers/900/subscriptions","data":[]}},{"object":"customer","id":"901","ref_id":"901","description":null,"email":"user_901@example.com","subscriptions":{"object":"list","url":"/v1/customers/901/subscriptions","data":[]}},{"object":"customer","id":"902","ref_id":"902","description":null,"email":"user_902@example.com","subscriptions":{"object":"list","url":"/v1/customers/902/subscriptions","data":[]}},{"object":"customer","id":"903","ref_id":"903","description":null,"email":"app3830@kensa.heroku.com","subscriptions":{"object":"list","url":"/v1/customers/903/subscriptions","data":[]}},{"object":"customer","id":"904","ref_id":"904","description":null,"email":"app16413261@heroku.com","subscriptions":{"object":"list","url":"/v1/customers/904/subscriptions","data":[]}},{"object":"customer","id":"905","ref_id":"905","description":null,"email":"user_905@example.com","subscriptions":{"object":"list","url":"/v1/customers/905/subscriptions","data":[]}},{"object":"customer","id":"906","ref_id":"906","description":null,"email":"user_906@example.com","subscriptions":{"object":"list","url":"/v1/customers/906/subscriptions","data":[]}},{"object":"customer","id":"907","ref_id":"907","description":null,"email":"app9219248@heroku.com","subscriptions":{"object":"list","url":"/v1/customers/907/subscriptions","data":[]}},{"object":"customer","id":"908","ref_id":"908","description":null,"email":"gojee@herokumanager.com","subscriptions":{"object":"list","url":"/v1/customers/908/subscriptions","data":[]}},{"object":"customer","id":"909","ref_id":"909","description":null,"email":"user_909@example.com","subscriptions":{"object":"list","url":"/v1/customers/909/subscriptions","data":[]}},{"object":"customer","id":"910","ref_id":"910","description":null,"email":"user_910@example.com","subscriptions":{"object":"list","url":"/v1/customers/910/subscriptions","data":[]}}]}'
|
60
|
+
http_version:
|
61
|
+
recorded_at: Sun, 26 Oct 2014 12:39:08 GMT
|
62
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: delete
|
5
|
+
uri: http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*; q=0.5, application/xml"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Boffin/v1 RubyBindings/0.0.1
|
16
|
+
Authorization:
|
17
|
+
- Token token=141d246d5e0774eaab3482259516dae9
|
18
|
+
Content-Type:
|
19
|
+
- application/x-www-form-urlencoded
|
20
|
+
Stripe-Version:
|
21
|
+
- v1
|
22
|
+
X-Stripe-Client-User-Agent:
|
23
|
+
- '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
|
24
|
+
tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
|
25
|
+
x86_64 x86_64 GNU/Linux"}'
|
26
|
+
response:
|
27
|
+
status:
|
28
|
+
code: 200
|
29
|
+
message: 'OK '
|
30
|
+
headers:
|
31
|
+
X-Frame-Options:
|
32
|
+
- SAMEORIGIN
|
33
|
+
X-Xss-Protection:
|
34
|
+
- 1; mode=block
|
35
|
+
X-Content-Type-Options:
|
36
|
+
- nosniff
|
37
|
+
Content-Type:
|
38
|
+
- application/json; charset=utf-8
|
39
|
+
Etag:
|
40
|
+
- '"5b689bd2f50df26c7e07c128bf983151"'
|
41
|
+
Cache-Control:
|
42
|
+
- max-age=0, private, must-revalidate
|
43
|
+
X-Request-Id:
|
44
|
+
- 5a68351b-454f-4eb1-9431-4a4550cad117
|
45
|
+
X-Runtime:
|
46
|
+
- '0.094349'
|
47
|
+
Server:
|
48
|
+
- WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
|
49
|
+
Date:
|
50
|
+
- Fri, 24 Oct 2014 18:08:56 GMT
|
51
|
+
Content-Length:
|
52
|
+
- '229'
|
53
|
+
Connection:
|
54
|
+
- Keep-Alive
|
55
|
+
Set-Cookie:
|
56
|
+
- request_method=DELETE; path=/
|
57
|
+
body:
|
58
|
+
encoding: UTF-8
|
59
|
+
string: '{"object":"subscription","start":"2014-01-01T00:00:00.000Z","canceled_at":"2014-10-24T18:08:56.000Z","metadata":{"provider":"heroku"},"plan":{"object":"plan","slug":"foo","amount":0,"currency":"usd"},"customer":{"ref_id":"1398"}}'
|
60
|
+
http_version:
|
61
|
+
recorded_at: Fri, 24 Oct 2014 18:08:56 GMT
|
62
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,66 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: http://api.boffin-dev.io:3000/v1/customers
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ref_id=test1234&description=Tim%20Williams&email=tim%40example.com
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*; q=0.5, application/xml"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Boffin/v1 RubyBindings/0.0.1
|
16
|
+
Authorization:
|
17
|
+
- Token token=141d246d5e0774eaab3482259516dae9
|
18
|
+
Content-Type:
|
19
|
+
- application/x-www-form-urlencoded
|
20
|
+
Stripe-Version:
|
21
|
+
- v1
|
22
|
+
X-Stripe-Client-User-Agent:
|
23
|
+
- '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
|
24
|
+
tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
|
25
|
+
x86_64 x86_64 GNU/Linux"}'
|
26
|
+
Content-Length:
|
27
|
+
- '66'
|
28
|
+
response:
|
29
|
+
status:
|
30
|
+
code: 201
|
31
|
+
message: 'Created '
|
32
|
+
headers:
|
33
|
+
X-Frame-Options:
|
34
|
+
- SAMEORIGIN
|
35
|
+
X-Xss-Protection:
|
36
|
+
- 1; mode=block
|
37
|
+
X-Content-Type-Options:
|
38
|
+
- nosniff
|
39
|
+
Location:
|
40
|
+
- http://api.boffin-dev.io:3000/v1/customers/5679
|
41
|
+
Content-Type:
|
42
|
+
- application/json; charset=utf-8
|
43
|
+
Etag:
|
44
|
+
- '"6244553f4534538268f711c45950f29e"'
|
45
|
+
Cache-Control:
|
46
|
+
- max-age=0, private, must-revalidate
|
47
|
+
X-Request-Id:
|
48
|
+
- 3d93498e-13bf-4b79-ac67-4f43402896d2
|
49
|
+
X-Runtime:
|
50
|
+
- '0.021902'
|
51
|
+
Server:
|
52
|
+
- WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
|
53
|
+
Date:
|
54
|
+
- Fri, 24 Oct 2014 15:51:26 GMT
|
55
|
+
Content-Length:
|
56
|
+
- '181'
|
57
|
+
Connection:
|
58
|
+
- Keep-Alive
|
59
|
+
Set-Cookie:
|
60
|
+
- request_method=POST; path=/
|
61
|
+
body:
|
62
|
+
encoding: UTF-8
|
63
|
+
string: '{"id":5679,"description":"Tim Williams","email":"tim@example.com","ref_id":"test1234","created_at":"2014-10-24T15:51:26.002Z","updated_at":"2014-10-24T15:51:26.002Z","product_id":4}'
|
64
|
+
http_version:
|
65
|
+
recorded_at: Fri, 24 Oct 2014 15:51:26 GMT
|
66
|
+
recorded_with: VCR 2.9.3
|
@@ -0,0 +1,66 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: plan=foo&metadata[provider]=heroku&start=2014-01-01%2000%3A00%3A00%20%2B0000
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*; q=0.5, application/xml"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- Boffin/v1 RubyBindings/0.0.1
|
16
|
+
Authorization:
|
17
|
+
- Token token=141d246d5e0774eaab3482259516dae9
|
18
|
+
Content-Type:
|
19
|
+
- application/x-www-form-urlencoded
|
20
|
+
Stripe-Version:
|
21
|
+
- v1
|
22
|
+
X-Stripe-Client-User-Agent:
|
23
|
+
- '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
|
24
|
+
tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
|
25
|
+
x86_64 x86_64 GNU/Linux"}'
|
26
|
+
Content-Length:
|
27
|
+
- '76'
|
28
|
+
response:
|
29
|
+
status:
|
30
|
+
code: 201
|
31
|
+
message: 'Created '
|
32
|
+
headers:
|
33
|
+
X-Frame-Options:
|
34
|
+
- SAMEORIGIN
|
35
|
+
X-Xss-Protection:
|
36
|
+
- 1; mode=block
|
37
|
+
X-Content-Type-Options:
|
38
|
+
- nosniff
|
39
|
+
Location:
|
40
|
+
- http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions/7066
|
41
|
+
Content-Type:
|
42
|
+
- application/json; charset=utf-8
|
43
|
+
Etag:
|
44
|
+
- '"4272e7f380bbdbaff2ebc14a016f06f0"'
|
45
|
+
Cache-Control:
|
46
|
+
- max-age=0, private, must-revalidate
|
47
|
+
X-Request-Id:
|
48
|
+
- 19030148-df93-442b-b672-13e215ce8bd3
|
49
|
+
X-Runtime:
|
50
|
+
- '0.363081'
|
51
|
+
Server:
|
52
|
+
- WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
|
53
|
+
Date:
|
54
|
+
- Fri, 24 Oct 2014 18:08:55 GMT
|
55
|
+
Content-Length:
|
56
|
+
- '207'
|
57
|
+
Connection:
|
58
|
+
- Keep-Alive
|
59
|
+
Set-Cookie:
|
60
|
+
- request_method=POST; path=/
|
61
|
+
body:
|
62
|
+
encoding: UTF-8
|
63
|
+
string: '{"object":"subscription","start":"2014-01-01T00:00:00.000Z","canceled_at":null,"metadata":{"provider":"heroku"},"plan":{"object":"plan","slug":"foo","amount":0,"currency":"usd"},"customer":{"ref_id":"1398"}}'
|
64
|
+
http_version:
|
65
|
+
recorded_at: Fri, 24 Oct 2014 18:08:55 GMT
|
66
|
+
recorded_with: VCR 2.9.3
|