boffinio 0.0.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.
- 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
|