payout 0.0.1 → 0.1.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 +4 -4
- data/lib/payout/response.rb +80 -0
- data/lib/payout/v1/balance.rb +13 -0
- data/lib/payout/v1/card.rb +29 -0
- data/lib/payout/v1/payment.rb +13 -0
- data/lib/payout/v1.rb +5 -0
- data/lib/payout/version.rb +3 -0
- data/lib/payout.rb +163 -0
- metadata +42 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85330fbe4dd8d6e1a4dd4fe9a3ebea9b548387d6
|
4
|
+
data.tar.gz: 5423abe20ab180b944ac6e1d8dbc896b5b1d2e7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c47bac307a46dacb00bb20e1fc892f7b6649a7894c8c6913c264654933d639fed7216658c5ec7e4423a964cce6e8630f53a03a0453acd187983ccc3342ce17f
|
7
|
+
data.tar.gz: bb4d6d13e77944bbcf7a3eb1c6749a0d61e77c06bc4753b037779018879f118d9700b5781ad6ce67715fc30c052d076e1effb167c27c242d977069f3d9413f9a
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
##
|
4
|
+
# Wraps a RestClient response to provide the Payout SDK interface.
|
5
|
+
module Payout
|
6
|
+
class Response
|
7
|
+
class << self
|
8
|
+
# Handles the response from RestClient, including any errors that may be
|
9
|
+
# raised.
|
10
|
+
def handle
|
11
|
+
new(yield)
|
12
|
+
rescue SocketError => e
|
13
|
+
_handle_restclient_connection_error(e)
|
14
|
+
rescue RestClient::ExceptionWithResponse => e
|
15
|
+
_handle_error_with_response(e)
|
16
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
17
|
+
_handle_restclient_connection_error(e)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def _handle_restclient_connection_error(error)
|
23
|
+
case error
|
24
|
+
when RestClient::RequestTimeout
|
25
|
+
fail TimeoutError
|
26
|
+
when RestClient::ServerBrokeConnection
|
27
|
+
fail ConnectionError, 'The server broke the connection before the ' \
|
28
|
+
'request could complete.'
|
29
|
+
when RestClient::SSLCertificateNotVerified
|
30
|
+
fail ConnectionError, 'Failed to verify SSL certificate.'
|
31
|
+
when SocketError
|
32
|
+
fail ConnectionError, 'An unexpected error occurred when trying to ' \
|
33
|
+
'connect to Payout. This could be a DNS issue. Check that you can ' \
|
34
|
+
'resolve live.payout.com and/or sandbox.payout.com.'
|
35
|
+
else
|
36
|
+
fail ConnectionError, 'An unexpected error occurred when trying to ' \
|
37
|
+
'connect to Payout. Try again or contact us at support@payout.com.'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def _handle_error_with_response(error)
|
42
|
+
if (resp = error.response)
|
43
|
+
fail AuthenticationError, 'invalid credentials' if resp.code == 401
|
44
|
+
new(resp)
|
45
|
+
else
|
46
|
+
_handle_restclient_connection_error(error)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end # Class Methods
|
50
|
+
|
51
|
+
attr_reader :code
|
52
|
+
attr_reader :body
|
53
|
+
|
54
|
+
def initialize(response)
|
55
|
+
@code = response.code
|
56
|
+
@body = response.body
|
57
|
+
_parse(response.body)
|
58
|
+
end
|
59
|
+
|
60
|
+
def successful?
|
61
|
+
[200, 201].include?(code)
|
62
|
+
end
|
63
|
+
|
64
|
+
def [](key)
|
65
|
+
@_data[key]
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_h
|
69
|
+
@_data.dup
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def _parse(body)
|
75
|
+
@_data = JSON.parse(body || '{}', symbolize_names: true)
|
76
|
+
rescue JSON::ParserError
|
77
|
+
@_data = {}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Payout
|
2
|
+
module V1::Card
|
3
|
+
class << self
|
4
|
+
def retrieve(token)
|
5
|
+
Payout.request(:get, "/v1/cards/#{token}")
|
6
|
+
end
|
7
|
+
|
8
|
+
def tokenize(params)
|
9
|
+
Payout.request(:post, '/v1/cards', params)
|
10
|
+
end
|
11
|
+
|
12
|
+
def update_customer(params)
|
13
|
+
params = params.dup
|
14
|
+
token = params.delete(:card_token) or
|
15
|
+
fail ArgumentError, 'missing card_token'
|
16
|
+
|
17
|
+
Payout.request(:put, "/v1/cards/#{token}/customer", params)
|
18
|
+
end
|
19
|
+
|
20
|
+
def credit(params)
|
21
|
+
params = params.dup
|
22
|
+
token = params.delete(:card_token) or
|
23
|
+
fail ArgumentError, 'missing card_token'
|
24
|
+
|
25
|
+
Payout.request(:post, "/v1/cards/#{token}/credits", params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end # V1::Card
|
29
|
+
end # Payout
|
data/lib/payout/v1.rb
ADDED
data/lib/payout.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'payout/version'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
require 'openssl'
|
5
|
+
require 'rest-client'
|
6
|
+
|
7
|
+
module Payout
|
8
|
+
autoload(:Response, 'payout/response')
|
9
|
+
autoload(:V1, 'payout/v1')
|
10
|
+
|
11
|
+
class Error < StandardError; end
|
12
|
+
class AuthenticationError < Error; end
|
13
|
+
class VersionError < Error; end
|
14
|
+
class ConnectionError < Error; end
|
15
|
+
class TimeoutError < ConnectionError; end
|
16
|
+
|
17
|
+
DEFAULT_API_VERSION = 1
|
18
|
+
DEFAULT_OPEN_TIMEOUT = 30
|
19
|
+
DEFAULT_READ_TIMEOUT = 80
|
20
|
+
SSL_CA_FILE = File.expand_path('../../data/ca-file.crt', __FILE__).freeze
|
21
|
+
|
22
|
+
class << self
|
23
|
+
def version
|
24
|
+
VERSION
|
25
|
+
end
|
26
|
+
|
27
|
+
def api_version
|
28
|
+
if const_defined?(:API_VERSION)
|
29
|
+
API_VERSION
|
30
|
+
else
|
31
|
+
self.api_version = DEFAULT_API_VERSION
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def api_url
|
36
|
+
@api_url || 'https://live.payout.com'
|
37
|
+
end
|
38
|
+
|
39
|
+
def api_token
|
40
|
+
@api_token || fail(AuthenticationError,
|
41
|
+
'Payout.api_token must be defined')
|
42
|
+
end
|
43
|
+
|
44
|
+
def api_secret
|
45
|
+
@api_secret || fail(AuthenticationError,
|
46
|
+
'Payout.api_secret must be defined')
|
47
|
+
end
|
48
|
+
|
49
|
+
def open_timeout
|
50
|
+
@open_timeout || DEFAULT_OPEN_TIMEOUT
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_timeout
|
54
|
+
@read_timeout || DEFAULT_READ_TIMEOUT
|
55
|
+
end
|
56
|
+
|
57
|
+
def api_version=(version)
|
58
|
+
fail ArgumentError, 'must be an integer' unless version.is_a?(Integer)
|
59
|
+
fail ArgumentError, 'must be a positive integer' unless version > 0
|
60
|
+
|
61
|
+
_include_version(version)
|
62
|
+
end
|
63
|
+
|
64
|
+
def api_url=(api_url)
|
65
|
+
if api_url
|
66
|
+
api_url = api_url.dup
|
67
|
+
api_url = api_url[0..-2] if api_url[-1] == '/'
|
68
|
+
end
|
69
|
+
|
70
|
+
@api_url = api_url.freeze
|
71
|
+
end
|
72
|
+
|
73
|
+
def api_token=(token)
|
74
|
+
@api_token = token.dup.freeze
|
75
|
+
end
|
76
|
+
|
77
|
+
def api_secret=(secret)
|
78
|
+
@api_secret = secret.dup.freeze
|
79
|
+
end
|
80
|
+
|
81
|
+
def open_timeout=(timeout)
|
82
|
+
fail ArgumentError, 'must be an integer' unless timeout.is_a?(Integer)
|
83
|
+
@open_timeout = timeout
|
84
|
+
end
|
85
|
+
|
86
|
+
def read_timeout=(timeout)
|
87
|
+
fail ArgumentError, 'must be an integer' unless timeout.is_a?(Integer)
|
88
|
+
@read_timeout = timeout
|
89
|
+
end
|
90
|
+
|
91
|
+
def request(verb, path, params = {})
|
92
|
+
Response.handle { request!(verb, path, params) }
|
93
|
+
end
|
94
|
+
|
95
|
+
def request!(verb, path, params)
|
96
|
+
url = _build_request_url(path)
|
97
|
+
headers = _default_headers
|
98
|
+
body = nil
|
99
|
+
|
100
|
+
case verb
|
101
|
+
when :get, :delete
|
102
|
+
headers[:params] = params if params && params.any?
|
103
|
+
when :post, :put
|
104
|
+
headers[:content_type] = 'application/json'
|
105
|
+
body = params.to_json if params && params.any?
|
106
|
+
else
|
107
|
+
fail ArgumentError, "invalid request verb: #{verb.inspect}"
|
108
|
+
end
|
109
|
+
|
110
|
+
_request(
|
111
|
+
verify_ssl: OpenSSL::SSL::VERIFY_PEER,
|
112
|
+
ssl_ca_file: SSL_CA_FILE,
|
113
|
+
open_timeout: open_timeout,
|
114
|
+
read_timeout: read_timeout,
|
115
|
+
method: verb,
|
116
|
+
url: url,
|
117
|
+
headers: headers,
|
118
|
+
payload: body
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def const_missing(name)
|
125
|
+
super if const_defined?(:API_VERSION)
|
126
|
+
self.api_version = DEFAULT_API_VERSION
|
127
|
+
super unless const_defined?(name)
|
128
|
+
const_get(name)
|
129
|
+
end
|
130
|
+
|
131
|
+
def _include_version(version)
|
132
|
+
if const_defined?(:API_VERSION)
|
133
|
+
fail VersionError, 'cannot change version after it has been initialized'
|
134
|
+
end
|
135
|
+
|
136
|
+
unless (version_const = "V#{version}") && const_defined?(version_const)
|
137
|
+
fail ArgumentError, 'unsupported version'
|
138
|
+
end
|
139
|
+
|
140
|
+
include const_get(version_const)
|
141
|
+
|
142
|
+
const_set(:API_VERSION, version)
|
143
|
+
end
|
144
|
+
|
145
|
+
def _build_request_url(path)
|
146
|
+
api_url + (path[0] == '/' ? path : "/#{path}")
|
147
|
+
end
|
148
|
+
|
149
|
+
def _default_headers
|
150
|
+
{
|
151
|
+
authorization: "Basic #{_encoded_credentials}"
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
def _encoded_credentials
|
156
|
+
Base64.strict_encode64("#{api_token}:#{api_secret}")
|
157
|
+
end
|
158
|
+
|
159
|
+
def _request(request_opts)
|
160
|
+
RestClient::Request.execute(request_opts)
|
161
|
+
end
|
162
|
+
end # Class Methods
|
163
|
+
end # Payout
|
metadata
CHANGED
@@ -1,22 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: payout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Honer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2016-01-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
14
42
|
email:
|
15
43
|
- robert@payout.com
|
16
44
|
executables: []
|
17
45
|
extensions: []
|
18
46
|
extra_rdoc_files: []
|
19
|
-
files:
|
47
|
+
files:
|
48
|
+
- lib/payout.rb
|
49
|
+
- lib/payout/response.rb
|
50
|
+
- lib/payout/v1.rb
|
51
|
+
- lib/payout/v1/balance.rb
|
52
|
+
- lib/payout/v1/card.rb
|
53
|
+
- lib/payout/v1/payment.rb
|
54
|
+
- lib/payout/version.rb
|
20
55
|
homepage: http://github.com/payout/payout-ruby
|
21
56
|
licenses:
|
22
57
|
- BSD
|
@@ -37,8 +72,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
72
|
version: '0'
|
38
73
|
requirements: []
|
39
74
|
rubyforge_project:
|
40
|
-
rubygems_version: 2.4.
|
75
|
+
rubygems_version: 2.4.8
|
41
76
|
signing_key:
|
42
77
|
specification_version: 4
|
43
|
-
summary:
|
78
|
+
summary: Payout your customers quickly and easily. See www.payout.com for more.
|
44
79
|
test_files: []
|