button 1.2.0 → 2.0.0
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 +5 -13
- data/CHANGELOG.md +5 -0
- data/README.md +112 -11
- data/lib/button/client.rb +5 -1
- data/lib/button/resources/accounts.rb +39 -0
- data/lib/button/resources/merchants.rb +23 -0
- data/lib/button/resources/resource.rb +10 -4
- data/lib/button/response.rb +44 -15
- data/lib/button/version.rb +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ODBkYTM3Nzc4ZjdiODU2MDEwZWJiN2FkZTg3NTRkOTJhZTU3NGMxOQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c08ec518d065b7b8546110e37a06ba0b8da850ee
|
4
|
+
data.tar.gz: dadccf3559487db05b8618cd01e11ba71558e655
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZjVjMjMxZGI4YTM4MmExNTM0ZDljOTg4NDRjMjIzZGIzYzlkMzJjMWE5N2U0
|
11
|
-
YmRiMzZiMTQ2MDZmNGQwMDI1Y2M3OTAxNTYwNWRiNTA1M2Y3ODU=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YmY1MGY3NjE4OTliYTU3Y2FjMTUwNjMwODkzMjYzZDNhNjg5YWI2MmU2OWUz
|
14
|
-
N2IzMjE1Yzg2OTVkZjM4YmU0NjMxNmMwYWMwNzI4YTE0YTAyZWEzNDk1MmU0
|
15
|
-
MzMxYWNhYjgxNjk1NGZiMTEyNDgwZjNkODliNTE0NTZiNDhiNDM=
|
6
|
+
metadata.gz: 0075f1a015a55e2524fd68c90593514bf935803f9965745342e4e4cc542cf1a269c846745392291982b9d24a6dbb06e4c9649b1e260c925aa1fe4971defbf05c
|
7
|
+
data.tar.gz: 953d707ea24f530da5d70bfb4dfdbab8f97240400266d37fd44706915230173df70d9da2e478484960c6843456532ddf6023c32083999c3456e9e066a42d32af
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -28,7 +28,7 @@ client = Button::Client.new('sk-XXX')
|
|
28
28
|
|
29
29
|
The client will always attempt to raise a `Button::ButtonClientError` in an error condition.
|
30
30
|
|
31
|
-
All API requests will return a `Button::Response` instance
|
31
|
+
All API requests will return a `Button::Response` instance. To access the response data, invoke `#data`.
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
require 'button'
|
@@ -41,17 +41,17 @@ rescue Button::ButtonClientError => error
|
|
41
41
|
puts error
|
42
42
|
end
|
43
43
|
|
44
|
-
puts response
|
44
|
+
puts response
|
45
45
|
# => Button::Response(button_order_id: btnorder-XXX, total: 60, ... )
|
46
46
|
|
47
|
-
puts response.
|
48
|
-
# => btnorder-XXX
|
49
|
-
|
50
|
-
puts response.to_hash()
|
47
|
+
puts response.data
|
51
48
|
# => {:button_order_id=>'btnorder-29de0b1436075ea6', :total=>60, ... }
|
49
|
+
|
50
|
+
puts response.data[:button_order_id]
|
51
|
+
# => btnorder-XXX
|
52
52
|
```
|
53
53
|
|
54
|
-
|
54
|
+
_n.b. the keys of the response hash will always be symbols._
|
55
55
|
|
56
56
|
## Configuration
|
57
57
|
|
@@ -77,7 +77,75 @@ The supported options are as follows:
|
|
77
77
|
|
78
78
|
## Resources
|
79
79
|
|
80
|
-
We currently expose
|
80
|
+
We currently expose the following resources to manage:
|
81
|
+
|
82
|
+
* [`Accounts`](#accounts)
|
83
|
+
* [`Merchants`](#merchants)
|
84
|
+
* [`Orders`](#orders)
|
85
|
+
|
86
|
+
### Accounts
|
87
|
+
|
88
|
+
##### all
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
require 'button'
|
92
|
+
|
93
|
+
client = Button::Client.new('sk-XXX')
|
94
|
+
|
95
|
+
response = client.accounts.all
|
96
|
+
|
97
|
+
puts response
|
98
|
+
# => Button::Response(2 elements)
|
99
|
+
```
|
100
|
+
|
101
|
+
##### transactions
|
102
|
+
|
103
|
+
_n.b. transactions is a paged endpoint. Take care to inspect `response.next_cursor` in case there's more data to be read._
|
104
|
+
|
105
|
+
Along with the required account id, you may also pass the following optional arguments as a Hash as the second argument:
|
106
|
+
|
107
|
+
* `:cursor` (String): An API cursor to fetch a specific set of results.
|
108
|
+
* `:start` (ISO-8601 datetime String): Fetch transactions after this time.
|
109
|
+
* `:end` (ISO-8601 datetime String): Fetch transactions before this time.
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
require 'button'
|
113
|
+
|
114
|
+
client = Button::Client.new('sk-XXX')
|
115
|
+
|
116
|
+
response = client.accounts.transactions('acc-XXX')
|
117
|
+
cursor = response.next_cursor
|
118
|
+
|
119
|
+
puts response
|
120
|
+
# => Button::Response(75 elements)
|
121
|
+
|
122
|
+
# Unpage all results
|
123
|
+
#
|
124
|
+
while !cursor.nil? do
|
125
|
+
response = client.accounts.transactions('acc-XXX', cursor: cursor)
|
126
|
+
cursor = response.next_cursor
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
### Merchants
|
131
|
+
|
132
|
+
##### all
|
133
|
+
|
134
|
+
You may also pass the following optional arguments as a Hash as the first argument:
|
135
|
+
|
136
|
+
* `:status` (String): Partnership status to filter by. One of ('approved', 'pending', or 'available')
|
137
|
+
* `:currency` (ISO-4217 String): Currency code to filter returned rates by
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
require 'button'
|
141
|
+
|
142
|
+
client = Button::Client.new('sk-XXX')
|
143
|
+
|
144
|
+
response = client.merchants.all(status: 'pending', currency: 'GBP')
|
145
|
+
|
146
|
+
puts response
|
147
|
+
# => Button::Response(23 elements)
|
148
|
+
```
|
81
149
|
|
82
150
|
### Orders
|
83
151
|
|
@@ -98,7 +166,7 @@ response = client.orders.create({
|
|
98
166
|
btn_ref: 'srctok-XXX'
|
99
167
|
})
|
100
168
|
|
101
|
-
puts response
|
169
|
+
puts response
|
102
170
|
# => Button::Response(button_order_id: btnorder-XXX, total: 50, ... )
|
103
171
|
```
|
104
172
|
|
@@ -111,9 +179,10 @@ client = Button::Client.new('sk-XXX')
|
|
111
179
|
|
112
180
|
response = client.orders.get('btnorder-XXX')
|
113
181
|
|
114
|
-
puts response
|
182
|
+
puts response
|
115
183
|
# => Button::Response(button_order_id: btnorder-XXX, total: 50, ... )
|
116
184
|
```
|
185
|
+
|
117
186
|
##### Update
|
118
187
|
|
119
188
|
```ruby
|
@@ -123,7 +192,7 @@ client = Button::Client.new('sk-XXX')
|
|
123
192
|
|
124
193
|
response = client.orders.update('btnorder-XXX', total: 60)
|
125
194
|
|
126
|
-
puts response
|
195
|
+
puts response
|
127
196
|
# => Button::Response(button_order_id: btnorder-XXX, total: 60, ... )
|
128
197
|
```
|
129
198
|
|
@@ -140,6 +209,38 @@ puts response
|
|
140
209
|
# => Button::Response()
|
141
210
|
```
|
142
211
|
|
212
|
+
## Response
|
213
|
+
|
214
|
+
An instance of the `Button::Response` class will be returned by all API methods. It is used to read the response data as well as collect any meta data about the response, like potential next and previous cursors to more data in a paged endpoint.
|
215
|
+
|
216
|
+
### Methods
|
217
|
+
|
218
|
+
#### data
|
219
|
+
|
220
|
+
returns the underlying response data
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
require 'button'
|
224
|
+
|
225
|
+
client = Button::Client.new('sk-XXX')
|
226
|
+
|
227
|
+
response = client.accounts.all
|
228
|
+
|
229
|
+
puts response
|
230
|
+
# => Button::Response(2 elements)
|
231
|
+
|
232
|
+
puts response.data
|
233
|
+
# => [ { ... }, { ... } ]
|
234
|
+
```
|
235
|
+
|
236
|
+
#### next_cursor
|
237
|
+
|
238
|
+
For any paged resource, `#next_cursor` will return a cursor to supply for the next page of results. If `#next_cursor` returns `nil`, then there are no more results.
|
239
|
+
|
240
|
+
#### prev_cursor
|
241
|
+
|
242
|
+
For any paged resource, `#prev_cursor` will return a cursor to supply for the previous page of results. If `#prev_cursor` returns `nil`, then there are no more results, err.. backwards.
|
243
|
+
|
143
244
|
## Utils
|
144
245
|
|
145
246
|
Utils houses generic helpers useful in a Button Integration.
|
data/lib/button/client.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'button/resources/accounts'
|
2
|
+
require 'button/resources/merchants'
|
1
3
|
require 'button/resources/orders'
|
2
4
|
require 'button/errors'
|
3
5
|
|
@@ -23,6 +25,8 @@ module Button
|
|
23
25
|
|
24
26
|
config_with_defaults = merge_defaults(config)
|
25
27
|
|
28
|
+
@accounts = Accounts.new(api_key, config_with_defaults)
|
29
|
+
@merchants = Merchants.new(api_key, config_with_defaults)
|
26
30
|
@orders = Orders.new(api_key, config_with_defaults)
|
27
31
|
end
|
28
32
|
|
@@ -37,7 +41,7 @@ module Button
|
|
37
41
|
}
|
38
42
|
end
|
39
43
|
|
40
|
-
attr_reader :orders
|
44
|
+
attr_reader :accounts, :merchants, :orders
|
41
45
|
private :merge_defaults
|
42
46
|
end
|
43
47
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'button/resources/resource'
|
2
|
+
|
3
|
+
module Button
|
4
|
+
# https://www.usebutton.com/developers/api-reference/
|
5
|
+
#
|
6
|
+
class Accounts < Resource
|
7
|
+
def path(account_id = nil)
|
8
|
+
return "/v1/affiliation/accounts/#{account_id}/transactions" if account_id
|
9
|
+
'/v1/affiliation/accounts'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Gets a list of available accounts
|
13
|
+
#
|
14
|
+
# @return [Button::Response] the API response
|
15
|
+
#
|
16
|
+
def all
|
17
|
+
api_get(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Gets a list of transactions for an account
|
21
|
+
#
|
22
|
+
# @param [String] account_id the account id to look up transactions for
|
23
|
+
# @option [String] cursor the account id to look up transactions for
|
24
|
+
# @option [ISO-8601 datetime String] start The start date to filter
|
25
|
+
# transactions
|
26
|
+
# @option [ISO-8601 datetime String] end The end date to filter
|
27
|
+
# transactions
|
28
|
+
# @return [Button::Response] the API response
|
29
|
+
#
|
30
|
+
def transactions(account_id, opts = {})
|
31
|
+
query = {}
|
32
|
+
query['cursor'] = opts[:cursor] if opts[:cursor]
|
33
|
+
query['start'] = opts[:start] if opts[:start]
|
34
|
+
query['end'] = opts[:end] if opts[:end]
|
35
|
+
|
36
|
+
api_get(path(account_id), query)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'button/resources/resource'
|
2
|
+
|
3
|
+
module Button
|
4
|
+
# https://www.usebutton.com/developers/api-reference/
|
5
|
+
#
|
6
|
+
class Merchants < Resource
|
7
|
+
# Gets a list of available merchants
|
8
|
+
#
|
9
|
+
# @option [String] status The status to filter by. One of ('approved',
|
10
|
+
# 'pending', or 'available')
|
11
|
+
# @option [ISO-4217 String] currency Currency code to filter returned rates
|
12
|
+
# by
|
13
|
+
# @return [Button::Response] the API response
|
14
|
+
#
|
15
|
+
def all(opts = {})
|
16
|
+
query = {}
|
17
|
+
query['status'] = opts[:status] if opts[:status]
|
18
|
+
query['currency'] = opts[:currency] if opts[:currency]
|
19
|
+
|
20
|
+
api_get('/v1/merchants', query)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'uri'
|
1
2
|
require 'net/http'
|
2
3
|
require 'json'
|
3
4
|
|
@@ -43,10 +44,13 @@ module Button
|
|
43
44
|
# Performs an HTTP GET at the provided path.
|
44
45
|
#
|
45
46
|
# @param [String] path the HTTP path
|
47
|
+
# @param [Hash=] query optional query params to send
|
46
48
|
# @return [Button::Response] the API response
|
47
49
|
#
|
48
|
-
def api_get(path)
|
49
|
-
|
50
|
+
def api_get(path, query = nil)
|
51
|
+
uri = URI(path)
|
52
|
+
uri.query = URI.encode_www_form(query) if query
|
53
|
+
api_request(Net::HTTP::Get.new(uri.to_s))
|
50
54
|
end
|
51
55
|
|
52
56
|
# Performs an HTTP POST at the provided path.
|
@@ -94,9 +98,11 @@ module Button
|
|
94
98
|
|
95
99
|
raise ButtonClientError, "Invalid response: #{parsed}" unless parsed[:meta].is_a?(Hash)
|
96
100
|
|
97
|
-
|
101
|
+
meta = parsed[:meta]
|
102
|
+
status = meta[:status]
|
103
|
+
response_data = parsed.fetch(:object, parsed.fetch(:objects, {}))
|
98
104
|
|
99
|
-
return Response.new(
|
105
|
+
return Response.new(meta, response_data) if status == 'ok'
|
100
106
|
raise ButtonClientError, "Unknown status: #{status}" unless status == 'error'
|
101
107
|
raise ButtonClientError, parsed[:error][:message] if parsed[:error].is_a?(Hash)
|
102
108
|
raise ButtonClientError, "Invalid response: #{parsed}"
|
data/lib/button/response.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'uri'
|
3
|
+
|
1
4
|
module Button
|
2
5
|
# Response is a simple proxy class for easy value unpacking from an API
|
3
6
|
# response. It is constructed with a hash and proxies method calls on the
|
@@ -5,33 +8,59 @@ module Button
|
|
5
8
|
#
|
6
9
|
# ## Usage
|
7
10
|
#
|
8
|
-
# response = Button::Response.new({
|
9
|
-
#
|
10
|
-
#
|
11
|
+
# response = Button::Response.new({
|
12
|
+
# prev: 'https://bloop.net/?cursor=1989',
|
13
|
+
# next: 'https://bloop.net/?cursor=1991'
|
14
|
+
# }, :a => 1, :b => "two")
|
15
|
+
#
|
16
|
+
# puts response.data
|
17
|
+
# puts response.next_cursor
|
18
|
+
# puts response.prev_cursor
|
11
19
|
#
|
12
20
|
class Response
|
13
|
-
def initialize(
|
14
|
-
@
|
21
|
+
def initialize(meta, response_data)
|
22
|
+
@meta = meta
|
23
|
+
@response_data = response_data
|
15
24
|
end
|
16
25
|
|
17
26
|
def to_s
|
18
|
-
|
19
|
-
|
20
|
-
|
27
|
+
repr = ''
|
28
|
+
|
29
|
+
if @response_data.is_a?(Hash)
|
30
|
+
repr = @response_data.reduce([]) do |acc, (name, value)|
|
31
|
+
acc + ["#{name}: #{value || 'nil'}"]
|
32
|
+
end.join(', ')
|
33
|
+
elsif @response_data.is_a?(Array)
|
34
|
+
repr = "#{@response_data.size} elements"
|
35
|
+
end
|
36
|
+
|
37
|
+
"Button::Response(#{repr})"
|
38
|
+
end
|
21
39
|
|
22
|
-
|
40
|
+
def data
|
41
|
+
@response_data
|
23
42
|
end
|
24
43
|
|
25
|
-
def
|
26
|
-
@
|
44
|
+
def next_cursor
|
45
|
+
Response.format_cursor(@meta.fetch(:next, nil))
|
27
46
|
end
|
28
47
|
|
29
|
-
def
|
30
|
-
@
|
48
|
+
def prev_cursor
|
49
|
+
Response.format_cursor(@meta.fetch(:prev, nil))
|
31
50
|
end
|
32
51
|
|
33
|
-
|
34
|
-
|
52
|
+
class << self
|
53
|
+
def format_cursor(cursor_url)
|
54
|
+
return nil unless cursor_url
|
55
|
+
|
56
|
+
parsed = URI(cursor_url)
|
57
|
+
return nil unless parsed.query
|
58
|
+
|
59
|
+
query = CGI.parse(parsed.query)
|
60
|
+
cursor = query.fetch('cursor', [])
|
61
|
+
|
62
|
+
cursor.empty? ? nil : cursor[0]
|
63
|
+
end
|
35
64
|
end
|
36
65
|
end
|
37
66
|
end
|
data/lib/button/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: button
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Button
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Button is a contextual acquisition channel and closed-loop attribution
|
14
14
|
and affiliation system for mobile commerce.
|
@@ -24,6 +24,8 @@ files:
|
|
24
24
|
- lib/button.rb
|
25
25
|
- lib/button/client.rb
|
26
26
|
- lib/button/errors.rb
|
27
|
+
- lib/button/resources/accounts.rb
|
28
|
+
- lib/button/resources/merchants.rb
|
27
29
|
- lib/button/resources/orders.rb
|
28
30
|
- lib/button/resources/resource.rb
|
29
31
|
- lib/button/response.rb
|
@@ -39,17 +41,17 @@ require_paths:
|
|
39
41
|
- lib
|
40
42
|
required_ruby_version: !ruby/object:Gem::Requirement
|
41
43
|
requirements:
|
42
|
-
- -
|
44
|
+
- - ">="
|
43
45
|
- !ruby/object:Gem::Version
|
44
46
|
version: 1.9.3
|
45
47
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
48
|
requirements:
|
47
|
-
- -
|
49
|
+
- - ">="
|
48
50
|
- !ruby/object:Gem::Version
|
49
51
|
version: '0'
|
50
52
|
requirements: []
|
51
53
|
rubyforge_project:
|
52
|
-
rubygems_version: 2.
|
54
|
+
rubygems_version: 2.5.1
|
53
55
|
signing_key:
|
54
56
|
specification_version: 4
|
55
57
|
summary: ruby client for the Button Order API
|