synapse_client 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/.coveralls.yml +1 -0
- data/.gitignore +15 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.md +116 -0
- data/Rakefile +11 -0
- data/lib/synapse_client.rb +137 -0
- data/lib/synapse_client/api_operations/create.rb +16 -0
- data/lib/synapse_client/api_operations/list.rb +17 -0
- data/lib/synapse_client/api_operations/response.rb +20 -0
- data/lib/synapse_client/api_resource.rb +50 -0
- data/lib/synapse_client/bank_account.rb +83 -0
- data/lib/synapse_client/customer.rb +140 -0
- data/lib/synapse_client/error.rb +42 -0
- data/lib/synapse_client/merchant.rb +24 -0
- data/lib/synapse_client/mfa.rb +26 -0
- data/lib/synapse_client/order.rb +65 -0
- data/lib/synapse_client/refreshed_tokens.rb +39 -0
- data/lib/synapse_client/security_question.rb +17 -0
- data/lib/synapse_client/util.rb +55 -0
- data/lib/synapse_client/version.rb +3 -0
- data/spec/spec_helper.rb +78 -0
- data/spec/synapse_client_bank_account_spec.rb +67 -0
- data/spec/synapse_client_customer_spec.rb +42 -0
- data/spec/synapse_client_order_spec.rb +53 -0
- data/spec/synapse_client_spec.rb +70 -0
- data/synapse_client.gemspec +34 -0
- metadata +253 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class BankAccount < APIResource
|
4
|
+
include SynapseClient::APIOperations::List
|
5
|
+
|
6
|
+
attr_accessor :name_on_account, :nickname
|
7
|
+
attr_accessor :date, :bank_name, :resource_uri
|
8
|
+
attr_accessor :account_class, :account_type
|
9
|
+
attr_accessor :routing_number_string, :account_number_string
|
10
|
+
attr_accessor :is_active, :is_buyer_default, :is_seller_default, :is_verified
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
options = Map.new(options)
|
14
|
+
|
15
|
+
@account_class = options[:account_class]
|
16
|
+
@account_number_string = options[:account_number_string]
|
17
|
+
@account_type = options[:account_type]
|
18
|
+
@bank_name = options[:bank_name]
|
19
|
+
@date = options[:date]
|
20
|
+
@id = options[:id] || options[:bank_id]
|
21
|
+
@is_active = options[:is_active]
|
22
|
+
@is_buyer_default = options[:is_buyer_default]
|
23
|
+
@is_seller_default = options[:is_seller_default]
|
24
|
+
@is_verified = options[:is_verified]
|
25
|
+
@name_on_account = options[:name_on_account]
|
26
|
+
@nickname = options[:nickname]
|
27
|
+
@resource_uri = options[:resource_uri]
|
28
|
+
@routing_number_string = options[:routing_number_string]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.api_resource_name
|
32
|
+
"bank"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.all(params={})
|
36
|
+
bank_accounts = list(params).banks
|
37
|
+
bank_accounts.map{|ba| BankAccount.new(ba)}
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.add(params={})
|
41
|
+
response = SynapseClient.request(:post, url + "add", params)
|
42
|
+
return response unless response.successful?
|
43
|
+
BankAccount.new(response.data.bank)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.link(params={})
|
47
|
+
response = SynapseClient.request(:post, url + "login", params)
|
48
|
+
return response unless response.successful?
|
49
|
+
|
50
|
+
if response.data["is_mfa"]
|
51
|
+
MFA.new(response.data.response)
|
52
|
+
else
|
53
|
+
response.data.banks.map do |bank|
|
54
|
+
BankAccount.new(bank)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.finish_linking(params={})
|
60
|
+
unless params[:bank]
|
61
|
+
raise ArgumentError.new("You must include the bank name when responding to an MFA question.")
|
62
|
+
end
|
63
|
+
unless params[:bank_account_token]
|
64
|
+
raise ArgumentError.new("You must include the bank account token when responding to an MFA question.")
|
65
|
+
end
|
66
|
+
unless params[:mfa]
|
67
|
+
raise ArgumentError.new("You must include the answer(s) when responding to an MFA question.")
|
68
|
+
end
|
69
|
+
|
70
|
+
response = SynapseClient.request(:post, url + "mfa", params)
|
71
|
+
return response unless response.successful?
|
72
|
+
|
73
|
+
if response.data["is_mfa"]
|
74
|
+
MFA.new(response.data.response)
|
75
|
+
else
|
76
|
+
response.data.banks.map do |bank|
|
77
|
+
BankAccount.new(bank)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class Customer < APIResource
|
4
|
+
|
5
|
+
attr_accessor :email, :fullname, :phonenumber, :ip_address
|
6
|
+
attr_accessor :access_token, :refresh_token, :expires_in
|
7
|
+
attr_accessor :username
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
options = Map.new(options)
|
11
|
+
|
12
|
+
@id = options[:id] || options[:user_id]
|
13
|
+
@email = options[:email]
|
14
|
+
@fullname = options[:fullname] || options[:name]
|
15
|
+
@phonenumber = options[:phonenumber] || options[:phone_number]
|
16
|
+
@ip_address = options[:ip_address]
|
17
|
+
|
18
|
+
@access_token = options[:access_token]
|
19
|
+
@refresh_token = options[:refresh_token]
|
20
|
+
@expires_in = options[:expires_in]
|
21
|
+
@username = options[:username]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.api_resource_name
|
25
|
+
"user" # see README.md
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.create(opts={})
|
29
|
+
Customer.new(opts).create
|
30
|
+
end
|
31
|
+
|
32
|
+
def create
|
33
|
+
headers = {"REMOTE_ADDR" => @ip_address}
|
34
|
+
response = SynapseClient.request(:post, url + "create", to_hash, headers)
|
35
|
+
|
36
|
+
return response unless response.successful?
|
37
|
+
update_attributes(response.data)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.retrieve(access_token)
|
41
|
+
response = SynapseClient.request(:post, url + "show", {:access_token => access_token})
|
42
|
+
|
43
|
+
return response unless response.successful?
|
44
|
+
Customer.new(response.data.user)
|
45
|
+
end
|
46
|
+
|
47
|
+
# TODO
|
48
|
+
def login
|
49
|
+
# use http://synapsepay.readme.io/v1.0/docs/authentication-login
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
def bank_accounts
|
54
|
+
BankAccount.all({:access_token => @access_token})
|
55
|
+
end
|
56
|
+
def primary_bank_account
|
57
|
+
@bank_accounts.select{|ba| ba.is_buyer_default}.first
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_bank_account(params={})
|
61
|
+
BankAccount.add(params.merge({
|
62
|
+
:access_token => @access_token,
|
63
|
+
:fullname => @fullname
|
64
|
+
}))
|
65
|
+
end
|
66
|
+
|
67
|
+
def link_bank_account(params={})
|
68
|
+
BankAccount.link(params.merge({
|
69
|
+
:access_token => @access_token
|
70
|
+
}))
|
71
|
+
end
|
72
|
+
|
73
|
+
def finish_linking_bank_account(params={})
|
74
|
+
BankAccount.finish_linking(params.merge({
|
75
|
+
:access_token => @access_token
|
76
|
+
}))
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
def orders
|
81
|
+
Order.all({:access_token => @access_token})
|
82
|
+
end
|
83
|
+
|
84
|
+
def add_order(params={})
|
85
|
+
if SynapseClient.merchant_synapse_id.nil?
|
86
|
+
raise ArgumentError.new("You need to set SynapseClient.merchant_synapse_id before you can submit orders.")
|
87
|
+
else
|
88
|
+
Order.create(params.merge({
|
89
|
+
:access_token => @access_token,
|
90
|
+
:seller_id => SynapseClient.merchant_synapse_id,
|
91
|
+
:bank_pay => "yes" # see README.md
|
92
|
+
}))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
=begin
|
97
|
+
def link_account(options = {}, client)
|
98
|
+
options.to_options!.compact
|
99
|
+
|
100
|
+
data = {
|
101
|
+
:bank => options[:bank_name],
|
102
|
+
:password => options[:password],
|
103
|
+
:pin => options[:pin] || "1234",
|
104
|
+
:username => options[:username]
|
105
|
+
}
|
106
|
+
|
107
|
+
request = SynapseClient::Request.new("/api/v2/bank/login/", data, client)
|
108
|
+
response = request.post
|
109
|
+
|
110
|
+
if response.instance_of?(SynapseClient::Error)
|
111
|
+
response
|
112
|
+
elsif response["is_mfa"]
|
113
|
+
SynapseClient::MFA.new(response["response"])
|
114
|
+
else
|
115
|
+
add_bank_accounts response["banks"]
|
116
|
+
@bank_accounts
|
117
|
+
end
|
118
|
+
end
|
119
|
+
def unlink_account(options = {}, client)
|
120
|
+
data = {
|
121
|
+
:bank_id => options.delete(:bank_id),
|
122
|
+
}
|
123
|
+
|
124
|
+
request = SynapseClient::Request.new("/api/v2/bank/delete/", data, client)
|
125
|
+
request.post
|
126
|
+
end
|
127
|
+
=end
|
128
|
+
|
129
|
+
|
130
|
+
private
|
131
|
+
def update_attributes(data)
|
132
|
+
@access_token = data.access_token
|
133
|
+
@refresh_token = data.refresh_token
|
134
|
+
@expires_in = data.expires_in
|
135
|
+
@username = data.username
|
136
|
+
return self
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class Error
|
4
|
+
|
5
|
+
attr_reader :message
|
6
|
+
attr_reader :title
|
7
|
+
attr_reader :code
|
8
|
+
attr_reader :exception
|
9
|
+
attr_reader :request
|
10
|
+
|
11
|
+
def initialize(exception, request)
|
12
|
+
@exception = exception
|
13
|
+
@request = request
|
14
|
+
|
15
|
+
#
|
16
|
+
begin
|
17
|
+
@message = @exception["reason"] || @exception["message"]
|
18
|
+
@title = @exception["title"]
|
19
|
+
rescue => e
|
20
|
+
# FIXME
|
21
|
+
# Rails.logger.error("Something went wrong with interacting with Synapse: #{ @exception.message }")
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
if @message.present? && @message.match(/error.*oauth.*authentication/i).present?
|
27
|
+
refreshed_tokens = SynapseClient::RefreshedTokens.new({
|
28
|
+
:old_access_token => @request.customer_access_token,
|
29
|
+
:old_refresh_token => @request.customer_refresh_token
|
30
|
+
})
|
31
|
+
|
32
|
+
refreshed_tokens.refresh_old_tokens
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def msg
|
38
|
+
(title || message).to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module SynapseClient
|
4
|
+
class Merchant
|
5
|
+
|
6
|
+
attr_accessor :client_id
|
7
|
+
attr_accessor :client_secret
|
8
|
+
attr_accessor :oauth_merchant_key
|
9
|
+
attr_accessor :merchant_email
|
10
|
+
attr_accessor :device_id
|
11
|
+
|
12
|
+
def initialize(options ={})
|
13
|
+
options = Map.new(options)
|
14
|
+
|
15
|
+
@client_id = options[:client_id] || ENV["SYNAPSE_CLIENT_ID"]
|
16
|
+
@client_secret = options[:client_secret] || ENV["SYNAPSE_CLIENT_SECRET"]
|
17
|
+
@oauth_merchant_key = options[:oauth_merchant_key] || ENV["SYNAPSE_OAUTH_MERCHANT_KEY"]
|
18
|
+
@merchant_email = options[:merchant_email] || ENV["SYNAPSE_MERCHANT_EMAIL"]
|
19
|
+
@device_id = options[:device_id] || ENV["SYNAPSE_DEVICE_ID"]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class MFA
|
4
|
+
|
5
|
+
attr_reader :type
|
6
|
+
attr_reader :questions
|
7
|
+
attr_reader :bank_access_token
|
8
|
+
|
9
|
+
def initialize(options={})
|
10
|
+
options = Map.new(options)
|
11
|
+
|
12
|
+
@bank_access_token = options[:access_token]
|
13
|
+
@type = options[:type]
|
14
|
+
|
15
|
+
if @type == "questions"
|
16
|
+
@questions = []
|
17
|
+
questions = options[:mfa]
|
18
|
+
questions.each do |q|
|
19
|
+
@questions.push q["question"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class Order < APIResource
|
4
|
+
include SynapseClient::APIOperations::List
|
5
|
+
|
6
|
+
attr_reader :status
|
7
|
+
attr_reader :amount
|
8
|
+
attr_reader :seller_email
|
9
|
+
attr_reader :seller_id
|
10
|
+
attr_reader :bank_pay
|
11
|
+
attr_reader :bank_id
|
12
|
+
attr_reader :note
|
13
|
+
attr_reader :date_settled
|
14
|
+
attr_reader :date
|
15
|
+
attr_reader :ticket_number
|
16
|
+
attr_reader :resource_uri
|
17
|
+
attr_reader :account_type
|
18
|
+
attr_reader :fee
|
19
|
+
|
20
|
+
def initialize(options = {})
|
21
|
+
options = Map.new(options)
|
22
|
+
|
23
|
+
update_attributes(options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.all(params={})
|
27
|
+
orders = list(params, "recent").orders
|
28
|
+
orders.map{|order| Order.new(order)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.create(params={})
|
32
|
+
response = SynapseClient.request(:post, url + "add", params)
|
33
|
+
|
34
|
+
return response unless response.successful?
|
35
|
+
Order.new(response.data.order)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.retrieve_endpoint
|
39
|
+
"poll"
|
40
|
+
end
|
41
|
+
|
42
|
+
def retrieve_params
|
43
|
+
{:order_id => @id}
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_attributes(options)
|
47
|
+
@status = options[:status]
|
48
|
+
@amount = options[:amount]
|
49
|
+
@seller_email = options[:seller_email]
|
50
|
+
@bank_pay = options[:bank_pay]
|
51
|
+
@bank_id = options[:bank_id]
|
52
|
+
@note = options[:note]
|
53
|
+
@date_settled = options[:date_settled]
|
54
|
+
@date = options[:date]
|
55
|
+
@id = options[:id]
|
56
|
+
@ticket_number = options[:ticket_number]
|
57
|
+
@resource_uri = options[:resource_uri]
|
58
|
+
@account_type = options[:account_type]
|
59
|
+
@fee = options[:fee]
|
60
|
+
@seller_id = options[:seller_id] || options[:seller].delete("seller_id") rescue nil
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
module SynapseClient
|
3
|
+
class RefreshedTokens
|
4
|
+
|
5
|
+
attr_reader :old_access_token
|
6
|
+
attr_reader :old_refresh_token
|
7
|
+
attr_reader :new_access_token
|
8
|
+
attr_reader :new_refresh_token
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
options = Map.new(options)
|
12
|
+
|
13
|
+
@old_access_token = options[:old_access_token]
|
14
|
+
@old_refresh_token = options[:old_refresh_token]
|
15
|
+
end
|
16
|
+
|
17
|
+
def refresh_old_tokens
|
18
|
+
data = {
|
19
|
+
:grant_type => "refresh_token",
|
20
|
+
:refresh_token => @old_refresh_token
|
21
|
+
}
|
22
|
+
|
23
|
+
request = SynapseClient::Request.new("/oauth2/access_token", data)
|
24
|
+
response = request.post
|
25
|
+
|
26
|
+
unless response.instance_of?(SynapseClient::Error)
|
27
|
+
self.new_access_token = response["access_token"]
|
28
|
+
self.new_refresh_token = response["refresh_token"]
|
29
|
+
|
30
|
+
return self
|
31
|
+
else
|
32
|
+
return response
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|