gyft 0.0.1 → 0.0.2
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 +4 -4
- data/README.md +225 -0
- data/gyft.gemspec +1 -0
- data/lib/gyft.rb +8 -0
- data/lib/gyft/account.rb +2 -0
- data/lib/gyft/card.rb +2 -0
- data/lib/gyft/category.rb +2 -0
- data/lib/gyft/client.rb +100 -0
- data/lib/gyft/client/health.rb +13 -0
- data/lib/gyft/client/reseller.rb +69 -0
- data/lib/gyft/merchant.rb +2 -0
- data/lib/gyft/transaction.rb +2 -0
- data/lib/gyft/version.rb +1 -1
- data/spec/gyft_spec.rb +18 -0
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00dbb14a4c26ddb4f896a49b20991d911ace9961
|
4
|
+
data.tar.gz: c7ac360ff24ff8d4b4928cd144e1db4df36e3374
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 519a6fa76e89dc5d070585652334ad4ceb78618ea19d3feb9e1eb6d7586899324c35d3490e71b4d4b6e84668b9274a8b8e2b85fd7a64fbc4d0ae3a886667c072
|
7
|
+
data.tar.gz: b478b953e428c936ef65367c77e8b167018b26174f465c0f2c9cad34576f4113f0fd79df77a29e5b137fcedb16575383a6576fd5dd7ee2c969d1b69091f24eda
|
data/README.md
CHANGED
@@ -1 +1,226 @@
|
|
1
1
|
# Ruby API library for the Gyft API
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/gyft) [](https://travis-ci.org/cbetta/gyft)
|
4
|
+
|
5
|
+
A wrapper for the [Gyft API](http://developer.gyft.com). Specification as per the [developer documentation](http://developer.gyft.com/io-docs).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Either install directly or via bundler.
|
10
|
+
|
11
|
+
```rb
|
12
|
+
gem 'gyft'
|
13
|
+
```
|
14
|
+
|
15
|
+
## Getting started
|
16
|
+
|
17
|
+
The client will accept the API key and secret either as parameters on initialization,
|
18
|
+
or as environment variables. Additionally an `environment` can be set to either
|
19
|
+
`sandbox` (default) or `production`.
|
20
|
+
|
21
|
+
```rb
|
22
|
+
require 'gyft'
|
23
|
+
|
24
|
+
# using parameters
|
25
|
+
client = Gyft::Client.new(api_key: '...', api_secret: '...', environment: 'production')
|
26
|
+
|
27
|
+
# using these environment variables are set:
|
28
|
+
# * GYFT_RESELLER_API_KEY
|
29
|
+
# * GYFT_RESELLER_API_SECRET
|
30
|
+
# * GYFT_RESELLER_API_ENVIRONMENT
|
31
|
+
client = Gyft::Client.new
|
32
|
+
|
33
|
+
# now you are ready for your first API call
|
34
|
+
client.reseller.shop_cards # => [#<Gyft::Card id=123, merchant_id="123", ...>, ...]
|
35
|
+
```
|
36
|
+
|
37
|
+
## API
|
38
|
+
|
39
|
+
### GET /health/check
|
40
|
+
|
41
|
+
```rb
|
42
|
+
# with a connection
|
43
|
+
> client.health.check
|
44
|
+
true
|
45
|
+
|
46
|
+
# without a connection
|
47
|
+
> client.health.check
|
48
|
+
false
|
49
|
+
```
|
50
|
+
|
51
|
+
### GET /reseller/shop_cards
|
52
|
+
|
53
|
+
Returns the shop cards available for purchase.
|
54
|
+
|
55
|
+
```rb
|
56
|
+
> cards = client.reseller.shop_cards
|
57
|
+
[#<Gyft::Card id=123, merchant_id="123", ...>, ...]
|
58
|
+
> cards.first
|
59
|
+
Gyft::Card {
|
60
|
+
:id => 3028,
|
61
|
+
:merchant_id => "211-1346844972352-24",
|
62
|
+
:merchant_name => "Foot Locker",
|
63
|
+
:long_description => "<p>Foot Locker is ...</p>",
|
64
|
+
:card_currency_code => "USD",
|
65
|
+
:opening_balance => 50.0,
|
66
|
+
:merchant_card_template_id => 3750,
|
67
|
+
:cover_image_url_hd => "http://imagestest.gyft.com/merchants_cards/c-211-1346844972355-64_cover_hd.png",
|
68
|
+
:merchant_icon_image_url_hd => "http://imagestest.gyft.com/merchants/i-211-1346844972353-0_hd.png"
|
69
|
+
}
|
70
|
+
```
|
71
|
+
|
72
|
+
### GET /reseller/categories
|
73
|
+
|
74
|
+
Returns all of the categories.
|
75
|
+
|
76
|
+
```rb
|
77
|
+
> categories = client.reseller.categories
|
78
|
+
[#<Gyft::Category id=4, name="Babies & Children">, ... ]
|
79
|
+
> categories.first
|
80
|
+
Gyft::Category {
|
81
|
+
:id => 4,
|
82
|
+
:name => "Babies & Children"
|
83
|
+
}
|
84
|
+
```
|
85
|
+
|
86
|
+
### GET /reseller/merchants
|
87
|
+
|
88
|
+
Returns all of the merchants.
|
89
|
+
|
90
|
+
```rb
|
91
|
+
> merchants = client.reseller.merchants
|
92
|
+
[#<Gyft::Merchant id="123", name="foobar.com", ...>, ... ]
|
93
|
+
> merchants.first
|
94
|
+
Gyft::Merchant {
|
95
|
+
:id => "1406228802381_103",
|
96
|
+
:name => "1-800-Baskets.com",
|
97
|
+
:description => "Gift baskets for every occasion. ",
|
98
|
+
:long_description => "<p>1-800-Baskets has ...</p>",
|
99
|
+
:country_code => "US",
|
100
|
+
:homepage_label => "Go to 1800baskets.com",
|
101
|
+
:homepage_url => "http://www.1800baskets.com",
|
102
|
+
:facebook_id => "229053644398",
|
103
|
+
:twitter_id => "1800baskets",
|
104
|
+
:google_id => "+1800baskets",
|
105
|
+
:shop_cards => [#
|
106
|
+
[0] Gyft::Card {
|
107
|
+
:id => 4456,
|
108
|
+
:currency_code => "USD",
|
109
|
+
:price => 25.0,
|
110
|
+
:opening_balance => 25.0
|
111
|
+
},
|
112
|
+
[1] Gyft::Card {
|
113
|
+
:id => 4461,
|
114
|
+
:currency_code => "USD",
|
115
|
+
:price => 50.0,
|
116
|
+
:opening_balance => 50.0
|
117
|
+
}
|
118
|
+
],
|
119
|
+
:categories => [
|
120
|
+
[0] Gyft::Category {
|
121
|
+
:id => 12,
|
122
|
+
:name => "Home Goods"
|
123
|
+
}
|
124
|
+
],
|
125
|
+
:meta_title => "Buy 1-800-Baskets.com Gift Cards | Gyft",
|
126
|
+
:meta_description => "1-800-Baskets.com",
|
127
|
+
:min_card_value => 25.0,
|
128
|
+
:max_card_value => 50.0,
|
129
|
+
:cover_image_url_hd => "http://imagestest.gyft.com/merchants_cards/default-08_cover_hd.png",
|
130
|
+
:google_plus_url => "https://plus.google.com/+1800baskets",
|
131
|
+
:twitter_url => "https://twitter.com/1800baskets",
|
132
|
+
:card_name => "1-800-Baskets.com",
|
133
|
+
:icon_url => "http://imagestest.gyft.com/merchants/1-800-baskets_hd.png",
|
134
|
+
:legal_disclaimer_html => "...",
|
135
|
+
:facebook_url => "http://www.facebook.com/229053644398"
|
136
|
+
}
|
137
|
+
```
|
138
|
+
|
139
|
+
### GET /reseller/account
|
140
|
+
|
141
|
+
Returns details of the reseller's account.
|
142
|
+
|
143
|
+
```rb
|
144
|
+
> account = client.reseller.account
|
145
|
+
Gyft::Account {
|
146
|
+
:id => "abc123",
|
147
|
+
:global_shop_cards => true,
|
148
|
+
|
149
|
+
:username => "foobar",
|
150
|
+
:name => "FooBar",
|
151
|
+
:application_name => "FooBar",
|
152
|
+
:contact_name => "FooBar Developer",
|
153
|
+
:contact_email => "foo@example.com",
|
154
|
+
:balance => 50000.0,
|
155
|
+
:balance_updated_when => 1469051680000
|
156
|
+
}
|
157
|
+
```
|
158
|
+
|
159
|
+
### GET /reseller/transactions
|
160
|
+
|
161
|
+
Returns a list of all the transactions for the reseller.
|
162
|
+
|
163
|
+
```rb
|
164
|
+
> transactions = client.reseller.transactions
|
165
|
+
[#<Gyft::Transaction id=123, type=1, amount=25.0, created_when=1469034701000>, ...]
|
166
|
+
> transactions.first
|
167
|
+
Gyft::Transaction {
|
168
|
+
:id => 123,
|
169
|
+
:type => 1,
|
170
|
+
:amount => 25.0,
|
171
|
+
:created_when => 1469034701000
|
172
|
+
}
|
173
|
+
```
|
174
|
+
|
175
|
+
### GET /transactions/last/:number_of_records
|
176
|
+
|
177
|
+
Returns a limited list of recent transactions for the reseller.
|
178
|
+
|
179
|
+
```rb
|
180
|
+
> transactions = client.reseller.transactions(last: 1)
|
181
|
+
[#<Gyft::Transaction id=123, type=1, amount=25.0, created_when=1469034701000>]
|
182
|
+
> transactions.first
|
183
|
+
Gyft::Transaction {
|
184
|
+
:id => 123,
|
185
|
+
:type => 1,
|
186
|
+
:amount => 25.0,
|
187
|
+
:created_when => 1469034701000
|
188
|
+
}
|
189
|
+
```
|
190
|
+
|
191
|
+
### GET /transactions/first/:number_of_records
|
192
|
+
|
193
|
+
Returns a limited list of initial transactions for the reseller.
|
194
|
+
|
195
|
+
```rb
|
196
|
+
> transactions = client.reseller.transactions(first: 1)
|
197
|
+
[#<Gyft::Transaction id=122, type=1, amount=25.0, created_when=1469034701000>]
|
198
|
+
> transactions.first
|
199
|
+
Gyft::Transaction {
|
200
|
+
:id => 122,
|
201
|
+
:type => 1,
|
202
|
+
:amount => -25.0,
|
203
|
+
:created_when => 1469034701000
|
204
|
+
}
|
205
|
+
```
|
206
|
+
|
207
|
+
### GET /transaction/:id
|
208
|
+
|
209
|
+
Returns a full details for a sent transaction
|
210
|
+
|
211
|
+
```rb
|
212
|
+
> client.transaction(123)
|
213
|
+
Gyft::Transaction {
|
214
|
+
:id => 123,
|
215
|
+
:merchant_name => "Grotto",
|
216
|
+
|
217
|
+
:amount => 25.0,
|
218
|
+
:sent_to => "customer@example.com",
|
219
|
+
:auto_delivered => "N",
|
220
|
+
:revealed => "N",
|
221
|
+
:gift_status => 6,
|
222
|
+
:card_status => 0,
|
223
|
+
:transaction_created => 1469034701000,
|
224
|
+
:gift_created => 1469034701000
|
225
|
+
}
|
226
|
+
```
|
data/gyft.gemspec
CHANGED
data/lib/gyft.rb
CHANGED
data/lib/gyft/account.rb
ADDED
data/lib/gyft/card.rb
ADDED
data/lib/gyft/client.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'digest'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Gyft
|
6
|
+
class Client
|
7
|
+
class Error < StandardError; end
|
8
|
+
class ServerError < Error; end
|
9
|
+
|
10
|
+
ENDPOINTS = {
|
11
|
+
'production' => 'api.gyft.com',
|
12
|
+
'sandbox' => 'apitest.gyft.com'
|
13
|
+
}
|
14
|
+
|
15
|
+
attr_accessor :api_key, :api_secret, :environment, :http
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
@api_key = options.fetch(:api_key) do
|
19
|
+
ENV['GYFT_RESELLER_API_KEY'] ||
|
20
|
+
ArgumentError.new("Missing required argument: api_key")
|
21
|
+
end
|
22
|
+
|
23
|
+
@api_secret = options.fetch(:api_secret) do
|
24
|
+
ENV['GYFT_RESELLER_API_SECRET'] ||
|
25
|
+
ArgumentError.new("Missing required argument: api_secret")
|
26
|
+
end
|
27
|
+
|
28
|
+
@environment = begin
|
29
|
+
environment = options.fetch(:environment) do
|
30
|
+
ENV['GYFT_RESELLER_API_ENVIRONMENT'] || 'sandbox'
|
31
|
+
end
|
32
|
+
unless %w{production sandbox}.include?(environment)
|
33
|
+
raise ArgumentError.new("Invalid argument: environment should be one of 'production' or 'sandbox'")
|
34
|
+
end
|
35
|
+
environment
|
36
|
+
end
|
37
|
+
|
38
|
+
@http = Net::HTTP.new(ENDPOINTS[environment], Net::HTTP.https_default_port)
|
39
|
+
http.use_ssl = true
|
40
|
+
end
|
41
|
+
|
42
|
+
def health
|
43
|
+
Gyft::Client::Health.new(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
def reseller
|
47
|
+
Gyft::Client::Reseller.new(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
def get(path, params = {}, headers = {})
|
51
|
+
uri, timestamp = uri_for(path, params)
|
52
|
+
message = Net::HTTP::Get.new(uri.request_uri)
|
53
|
+
message['x-sig-timestamp'] = timestamp
|
54
|
+
headers.each { |key, value| message[key] = value }
|
55
|
+
transmit(message)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def uri_for(path, params = {})
|
61
|
+
uri = URI("https://#{ENDPOINTS[environment]}/mashery/v1#{path}")
|
62
|
+
sig, timestamp = signature
|
63
|
+
uri.query = URI.encode_www_form({
|
64
|
+
api_key: api_key,
|
65
|
+
sig: sig
|
66
|
+
})
|
67
|
+
[uri, timestamp]
|
68
|
+
end
|
69
|
+
|
70
|
+
def signature
|
71
|
+
timestamp = Time.now.getutc.to_i.to_s
|
72
|
+
plaintext = api_key + api_secret + timestamp
|
73
|
+
[Digest::SHA256.new.hexdigest(plaintext), timestamp]
|
74
|
+
end
|
75
|
+
|
76
|
+
def transmit(message)
|
77
|
+
parse(http.request(message))
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse response
|
81
|
+
case response
|
82
|
+
when Net::HTTPSuccess
|
83
|
+
json?(response) ? JSON.parse(response.body) : response.body
|
84
|
+
else
|
85
|
+
if json?(response)
|
86
|
+
raise ServerError, "HTTP #{response.code}: #{JSON.parse(response.body)}"
|
87
|
+
else
|
88
|
+
raise ServerError, "HTTP #{response.code}: #{response.body}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def json?(response)
|
94
|
+
content_type = response['Content-Type']
|
95
|
+
json_header = content_type && content_type.split(';').first == 'application/json'
|
96
|
+
has_body = response.body && response.body.length > 0
|
97
|
+
json_header && has_body
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
require 'awesome_print'
|
3
|
+
|
4
|
+
class Gyft::Client::Reseller
|
5
|
+
|
6
|
+
def initialize client
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def shop_cards
|
11
|
+
@client.get('/reseller/shop_cards').map do |card|
|
12
|
+
Gyft::Card.new(card)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def categories
|
17
|
+
@client.get('/reseller/categories')['details'].map do |category|
|
18
|
+
Gyft::Category.new(category)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def merchants
|
23
|
+
@client.get('/reseller/merchants')['details'].map do |merchant|
|
24
|
+
merchant = Gyft::Merchant.new(merchant)
|
25
|
+
merchant.shop_cards = merchant.shop_cards.map do |card|
|
26
|
+
Gyft::Card.new(card)
|
27
|
+
end
|
28
|
+
merchant.categories = merchant.categories.map do |category|
|
29
|
+
Gyft::Category.new(category)
|
30
|
+
end
|
31
|
+
merchant
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def account
|
36
|
+
result = @client.get('/reseller/account')
|
37
|
+
Gyft::Account.new(result)
|
38
|
+
end
|
39
|
+
|
40
|
+
def transactions options = {}
|
41
|
+
path = transactions_path_for(options)
|
42
|
+
|
43
|
+
@client.get(path).map do |transaction|
|
44
|
+
Gyft::Transaction.new(transaction)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def transaction id
|
49
|
+
result = @client.get("/reseller/transaction/#{id}")
|
50
|
+
Gyft::Transaction.new(result)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def transactions_path_for(options)
|
56
|
+
last = options[:last]
|
57
|
+
first = options[:first]
|
58
|
+
|
59
|
+
path = begin
|
60
|
+
if last && last > 0
|
61
|
+
"/reseller/transactions/last/#{last}"
|
62
|
+
elsif first && first > 0
|
63
|
+
"/reseller/transactions/first/#{first}"
|
64
|
+
else
|
65
|
+
'/reseller/transactions'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/gyft/version.rb
CHANGED
data/spec/gyft_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'webmock/minitest'
|
3
|
+
require 'gyft'
|
4
|
+
|
5
|
+
describe 'Gyft::Reseller' do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@client = Gyft::Client.new(api_key: '123', api_secret: '234')
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.health.check' do
|
12
|
+
it 'should return the result' do
|
13
|
+
stub_request(:get, /apitest.gyft.com\/mashery/)
|
14
|
+
.to_return(status: 200, body: "", headers: {})
|
15
|
+
@client.health.check.must_equal(true)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gyft
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cristiano Betta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-07-
|
11
|
+
date: 2016-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: awesome_print
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Wrapper for the Gyft API
|
56
70
|
email: cbetta@gmail.com
|
57
71
|
executables: []
|
@@ -62,7 +76,16 @@ files:
|
|
62
76
|
- README.md
|
63
77
|
- gyft.gemspec
|
64
78
|
- lib/gyft.rb
|
79
|
+
- lib/gyft/account.rb
|
80
|
+
- lib/gyft/card.rb
|
81
|
+
- lib/gyft/category.rb
|
82
|
+
- lib/gyft/client.rb
|
83
|
+
- lib/gyft/client/health.rb
|
84
|
+
- lib/gyft/client/reseller.rb
|
85
|
+
- lib/gyft/merchant.rb
|
86
|
+
- lib/gyft/transaction.rb
|
65
87
|
- lib/gyft/version.rb
|
88
|
+
- spec/gyft_spec.rb
|
66
89
|
homepage: https://github.com/cbetta/gyft
|
67
90
|
licenses:
|
68
91
|
- MIT
|