synapse_pay_rest 0.0.11 → 0.0.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ef0de243116afb622eb99e91833b0bfc2084101f
4
- data.tar.gz: 3467d9cf79f9f7bf9b0d235539d4b2450b3d1a55
3
+ metadata.gz: 4dbdc072bf2803c60e736b7dd86c3ee77a116051
4
+ data.tar.gz: 54a9502bfcabffb266b2cb9b7a0b98f95ecd3fbe
5
5
  SHA512:
6
- metadata.gz: 53779eec31d4480ac9e2c1c4afe0ee66851f717e80a1f2849c8a20719b87f113b76f09863657d5a4d5fc53bec4aa4fc5b190729d41c462ff0c2dd0261d912d9c
7
- data.tar.gz: 16cfa1aaae00c28147f1034b7205422ee5bb1b08f28e222c5fb418c127f0397da8cfb41768b3c1051d5996e3e85bcc616a31cc0701459de0e5a950ad7b50ec2b
6
+ metadata.gz: 4fd8d2bf9dadecaed2e2e54e97cffb8bc0a5f318638916b270987bc5ca752133a837de4d9f9c68e02bc182411973f4b6bd1f83dc0c5e23dbbea127010a0c8231
7
+ data.tar.gz: 57b16b876a60d60109a812c487609fefdd0c91ece4d86c456049f7762ad8ae9b400bc0ee43f6973b6f795f7930a652ca03f3c2fbfc144dba6721acf0e07423f8
data/.gitignore ADDED
@@ -0,0 +1,39 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ ## Specific to RubyMotion:
14
+ .dat*
15
+ .repl_history
16
+ build/
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalisation:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ # Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
37
+
38
+
39
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in your *.gemspec file
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ synapse_pay_rest (0.0.10)
5
+ rest-client
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ ansi (1.5.0)
11
+ builder (3.2.2)
12
+ domain_name (0.5.25)
13
+ unf (>= 0.0.5, < 1.0.0)
14
+ http-cookie (1.0.2)
15
+ domain_name (~> 0.5)
16
+ mime-types (2.6.2)
17
+ minitest (5.8.2)
18
+ minitest-reporters (1.1.5)
19
+ ansi
20
+ builder
21
+ minitest (>= 5.0)
22
+ ruby-progressbar
23
+ netrc (0.11.0)
24
+ rake (10.4.2)
25
+ rest-client (1.8.0)
26
+ http-cookie (>= 1.0.2, < 2.0)
27
+ mime-types (>= 1.16, < 3.0)
28
+ netrc (~> 0.7)
29
+ ruby-progressbar (1.7.5)
30
+ unf (0.1.4)
31
+ unf_ext
32
+ unf_ext (0.0.7.1)
33
+
34
+ PLATFORMS
35
+ ruby
36
+
37
+ DEPENDENCIES
38
+ bundler (~> 1.10)
39
+ minitest
40
+ minitest-reporters
41
+ rake (~> 10.0)
42
+ synapse_pay_rest!
43
+
44
+ BUNDLED WITH
45
+ 1.10.6
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ ## SynapsePayRest-Ruby
2
+
3
+ Simple API wrapper for SynapsePay REST V3 API. This wrapper aims to handle the headers for each API request and appropriate error handling.
4
+
5
+
6
+ ## Code Example
7
+
8
+ Check out the samples.md and our API documentation(http://docs.synapsepay.com/v3.1) for examples.
9
+
10
+ ## Installation
11
+
12
+ gem install synapse_pay_rest
13
+
14
+ ## License
15
+
16
+ The MIT License (MIT)
17
+
18
+ Copyright (c) 2014 SynapsePay LLC
19
+
20
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
21
+ this software and associated documentation files (the "Software"), to deal in
22
+ the Software without restriction, including without limitation the rights to
23
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
24
+ the Software, and to permit persons to whom the Software is furnished to do so,
25
+ subject to the following conditions:
26
+
27
+ The above copyright notice and this permission notice shall be included in all
28
+ copies or substantial portions of the Software.
29
+
30
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
32
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
33
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
34
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -1,30 +1,25 @@
1
- # Basic wrapper around the the requests library.
2
- require_relative "synapse_pay_rest/http_client"
3
- # Assign all the api classes
4
- require_relative "synapse_pay_rest/api/Users"
5
- require_relative "synapse_pay_rest/api/Nodes"
6
- require_relative "synapse_pay_rest/api/Trans"
1
+ require "synapse_pay_rest/http_client"
2
+ require "synapse_pay_rest/error"
3
+ require "synapse_pay_rest/version"
4
+ require "synapse_pay_rest/api/users"
5
+ require "synapse_pay_rest/api/nodes"
6
+ require "synapse_pay_rest/api/trans"
7
7
 
8
8
  module SynapsePayRest
9
- class Client
9
+ class Client
10
+ attr_accessor :client, :users, :nodes, :trans
10
11
 
11
- attr_accessor :client
12
- attr_accessor :users
13
- attr_accessor :nodes
14
- attr_accessor :trans
12
+ def initialize(options: raise("options is required"), user_id: nil)
13
+ base_url = if options['development_mode']
14
+ 'https://sandbox.synapsepay.com/api/3'
15
+ else
16
+ 'https://synapsepay.com/api/3'
17
+ end
15
18
 
16
- def initialize(options: raise("options is required"), user_id: nil)
17
- base_url = 'https://synapsepay.com/api/3'
18
- if options.has_key?('development_mode')
19
- if options['development_mode']
20
- base_url = 'https://sandbox.synapsepay.com/api/3'
21
- end
22
- end
23
-
24
- @client = HTTPClient.new options, base_url, user_id: user_id
25
- @users = Users.new @client
26
- @nodes = Nodes.new @client
27
- @trans = Trans.new @client
28
- end
29
- end
19
+ @client = HTTPClient.new options, base_url, user_id: user_id
20
+ @users = Users.new @client
21
+ @nodes = Nodes.new @client
22
+ @trans = Trans.new @client
23
+ end
24
+ end
30
25
  end
@@ -0,0 +1,46 @@
1
+ module SynapsePayRest
2
+ class Nodes
3
+
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def create_node_path(node_id: nil)
11
+ path = ['/users', client.user_id, 'nodes' ]
12
+ path << node_id if node_id
13
+ return path.join('/')
14
+ end
15
+
16
+ def add(payload: raise("payload is required"))
17
+ path = create_node_path
18
+ client.post(path, payload)
19
+ end
20
+
21
+ def get(node_id: nil, page: nil)
22
+ # If node_id is nil then create_node_path will handle it just fine
23
+ path = create_node_path(node_id: node_id)
24
+ path += "?page=#{page}" if page
25
+ client.get(path)
26
+ end
27
+
28
+ def verify(node_id: nil, payload: raise("payload is required"))
29
+ if node_id
30
+ # verify microdeposits
31
+ path = create_node_path(node_id: node_id)
32
+ response = @client.patch(path, payload)
33
+ else
34
+ # verify MFA question(s)
35
+ path = create_node_path
36
+ response = @client.post(path, payload)
37
+ end
38
+ response
39
+ end
40
+
41
+ def delete(node_id: raise("node_id is required"))
42
+ path = create_node_path(node_id: node_id)
43
+ client.delete(path)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,38 @@
1
+ module SynapsePayRest
2
+ class Trans
3
+
4
+ attr_accessor :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def create_transaction_path(node_id: raise("node_id is required"), trans_id: nil)
11
+ path = ['/users', client.user_id, 'nodes', node_id, 'trans' ]
12
+ path << trans_id if trans_id
13
+ return path.join('/')
14
+ end
15
+
16
+ def create(node_id: raise("node_id is required"), payload: raise("payload is required"))
17
+ path = create_transaction_path(node_id: node_id)
18
+ client.post(path, payload)
19
+ end
20
+
21
+ def update(node_id: raise("node_id is required"), trans_id: raise("trans_id is required"), payload: raise("payload is required"))
22
+ path = create_transaction_path(node_id: node_id, trans_id: trans_id)
23
+ client.patch(path, payload)
24
+ end
25
+
26
+ def get(node_id: raise("node_id is required"), trans_id: nil, page: nil)
27
+ path = create_transaction_path(node_id: node_id, trans_id: trans_id)
28
+ # This part really should just be a generic params generator
29
+ path += "?page=#{page}" if page
30
+ client.get(path)
31
+ end
32
+
33
+ def delete(node_id: raise("node_id is required"), trans_id: raise("trans_id is required"))
34
+ path = create_transaction_path(node_id: node_id, trans_id: trans_id)
35
+ client.delete(path)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,97 @@
1
+ require 'mime-types'
2
+ require 'base64'
3
+ require 'open-uri'
4
+
5
+ module SynapsePayRest
6
+ class Users
7
+ # Should refactor this to HTTPClient
8
+ VALID_QUERY_PARAMS = [:query, :page, :per_page].freeze
9
+
10
+ attr_accessor :client
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+
16
+ def create_user_path(user_id: nil)
17
+ path = ['/users']
18
+ path << user_id if user_id
19
+ return path.join('/')
20
+ end
21
+
22
+ def refresh(payload: raise("payload is required"))
23
+ path = "/oauth/#{@client.user_id}"
24
+ response = @client.post(path, payload)
25
+ client.update_headers(oauth_key: response['oauth_key']) if response['oauth_key']
26
+ return response
27
+ end
28
+
29
+ def get(user_id: nil, options: {})
30
+ path = create_user_path(user_id: user_id)
31
+
32
+ if options[:user_id]
33
+ response = client.get(path)
34
+ client.update_headers(user_id: response['_id']) if response['_id']
35
+ return response
36
+ end
37
+
38
+ # Should factor this out into HTTPClient
39
+ params = VALID_QUERY_PARAMS.map do |p|
40
+ options[p] ? "#{p}=#{options[p]}" : nil
41
+ end.compact
42
+
43
+ # Probably should use CGI or RestClient's param builder instead of
44
+ # rolling our own, probably error-prone and untested version
45
+ # https://github.com/rest-client/rest-client#usage-raw-url
46
+ path += '?' + params.join('&') if params.any?
47
+ client.get(path)
48
+ end
49
+
50
+ def update(payload: raise("payload is required"))
51
+ path = create_user_path(user_id: client.user_id)
52
+ client.patch(path, payload)
53
+ end
54
+
55
+ def create(payload: raise("payload is required"))
56
+ path = create_user_path
57
+ response = client.post(path, payload)
58
+ client.update_headers(user_id: response['_id']) if response['_id']
59
+ return response
60
+ end
61
+
62
+ def add_doc(payload: raise("payload is required"))
63
+ path = create_user_path(user_id: client.user_id)
64
+ client.patch(path, payload)
65
+ end
66
+
67
+ def answer_kba(payload: raise("payload is required"))
68
+ path = create_user_path(user_id: client.user_id)
69
+ client.patch(path, payload)
70
+ end
71
+
72
+ def attach_file(file_path: raise("file_path is required"))
73
+ file_contents = open(file_path) { |f| f.read }
74
+ file_type = MIME::Types.type_for(file_path).first.try(:content_type)
75
+ if file_type.nil?
76
+ raise("File type not found. Use attach_file_with_file_type(file_path: <file_path>, file_type: <file_type>)")
77
+ else
78
+ attach_file_with_file_type(file_path: file_path, file_type: file_type)
79
+ end
80
+ end
81
+
82
+ def attach_file_with_file_type(file_path: raise("file_path is required"), file_type: raise("file_type is required"))
83
+ path = create_user_path(user_id: @client.user_id)
84
+ file_contents = open(file_path) { |f| f.read }
85
+ encoded = Base64.encode64(file_contents)
86
+ mime_padding = "data:#{file_type};base64,"
87
+ base64_attachment = mime_padding + encoded
88
+
89
+ payload = {
90
+ 'doc' => {
91
+ 'attachment' => base64_attachment
92
+ }
93
+ }
94
+ client.patch(path, payload)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,114 @@
1
+ module SynapsePayRest
2
+ class Error < StandardError
3
+ # Raised on a 4xx HTTP status code
4
+ ClientError = Class.new(self)
5
+
6
+ # Raised on the HTTP status code 400
7
+ BadRequest = Class.new(ClientError)
8
+
9
+ # Raised on the HTTP status code 401
10
+ Unauthorized = Class.new(ClientError)
11
+
12
+ # Raised on the HTTP status code 402
13
+ RequestDeclined = Class.new(ClientError)
14
+
15
+ # Raised on the HTTP status code 403
16
+ Forbidden = Class.new(ClientError)
17
+
18
+ # Raised on the HTTP status code 404
19
+ NotFound = Class.new(ClientError)
20
+
21
+ # Raised on the HTTP status code 406
22
+ NotAcceptable = Class.new(ClientError)
23
+
24
+ # Raised on the HTTP status code 409
25
+ Conflict = Class.new(ClientError)
26
+
27
+ # Raised on the HTTP status code 415
28
+ UnsupportedMediaType = Class.new(ClientError)
29
+
30
+ # Raised on the HTTP status code 422
31
+ UnprocessableEntity = Class.new(ClientError)
32
+
33
+ # Raised on the HTTP status code 429
34
+ TooManyRequests = Class.new(ClientError)
35
+
36
+ # Raised on a 5xx HTTP status code
37
+ ServerError = Class.new(self)
38
+
39
+ # Raised on the HTTP status code 500
40
+ InternalServerError = Class.new(ServerError)
41
+
42
+ # Raised on the HTTP status code 502
43
+ BadGateway = Class.new(ServerError)
44
+
45
+ # Raised on the HTTP status code 503
46
+ ServiceUnavailable = Class.new(ServerError)
47
+
48
+ # Raised on the HTTP status code 504
49
+ GatewayTimeout = Class.new(ServerError)
50
+
51
+ ERRORS = {
52
+ 400 => SynapsePayRest::Error::BadRequest,
53
+ 401 => SynapsePayRest::Error::Unauthorized,
54
+ 402 => SynapsePayRest::Error::RequestDeclined,
55
+ 403 => SynapsePayRest::Error::Forbidden,
56
+ 404 => SynapsePayRest::Error::NotFound,
57
+ 406 => SynapsePayRest::Error::NotAcceptable,
58
+ 409 => SynapsePayRest::Error::Conflict,
59
+ 415 => SynapsePayRest::Error::UnsupportedMediaType,
60
+ 422 => SynapsePayRest::Error::UnprocessableEntity,
61
+ 429 => SynapsePayRest::Error::TooManyRequests,
62
+ 500 => SynapsePayRest::Error::InternalServerError,
63
+ 502 => SynapsePayRest::Error::BadGateway,
64
+ 503 => SynapsePayRest::Error::ServiceUnavailable,
65
+ 504 => SynapsePayRest::Error::GatewayTimeout,
66
+ }
67
+
68
+ # The SynapsePay API Error Code
69
+ #
70
+ # @return [Integer]
71
+ attr_reader :code
72
+
73
+ # The JSON HTTP response in Hash form
74
+ #
75
+ # @return [Hash]
76
+ attr_reader :response
77
+
78
+ class << self
79
+ # Create a new error from an HTTP response
80
+ #
81
+ # @param body [String]
82
+ # @param code [Integer]
83
+ # @return [SynapsePayRest::Error]
84
+ def error_from_response(body, code)
85
+ klass = ERRORS[code] || SynapsePayRest::Error
86
+ message, error_code = parse_error(body)
87
+ klass.new(message: message, code: error_code, response: body)
88
+ end
89
+
90
+ private
91
+
92
+ def parse_error(body)
93
+ if body.nil? || body.empty?
94
+ ['', nil]
95
+ elsif body.is_a?(Hash) && body['error'].is_a?(Hash)
96
+ [body['error']['en'], body['error_code']]
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ # Initializes a new Error object
103
+ #
104
+ # @param message [Exception, String]
105
+ # @param code [Integer]
106
+ # @param response [Hash]
107
+ # @return [SynapsePayRest::Error]
108
+ def initialize(message: '', code: nil, response: {})
109
+ super(message)
110
+ @code = code
111
+ @response = response
112
+ end
113
+ end
114
+ end