dwolla-ruby 2.6.4 → 2.6.5

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.
Files changed (46) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +8 -8
  3. data/.travis.yml +6 -6
  4. data/Gemfile +1 -1
  5. data/README.md +198 -192
  6. data/Rakefile +8 -8
  7. data/dwolla-ruby.gemspec +27 -27
  8. data/examples/balance.rb +15 -15
  9. data/examples/contacts.rb +32 -32
  10. data/examples/fundingSources.rb +39 -39
  11. data/examples/oauth.rb +59 -50
  12. data/examples/offsiteGateway.rb +31 -31
  13. data/examples/transactions.rb +72 -38
  14. data/examples/users.rb +30 -30
  15. data/gemfiles/json.gemfile +2 -2
  16. data/lib/dwolla.rb +326 -326
  17. data/lib/dwolla/accounts.rb +27 -27
  18. data/lib/dwolla/balance.rb +15 -15
  19. data/lib/dwolla/contacts.rb +30 -30
  20. data/lib/dwolla/errors/api_connection_error.rb +3 -3
  21. data/lib/dwolla/errors/api_error.rb +3 -3
  22. data/lib/dwolla/errors/authentication_error.rb +3 -3
  23. data/lib/dwolla/errors/dwolla_error.rb +19 -19
  24. data/lib/dwolla/errors/invalid_request_error.rb +10 -10
  25. data/lib/dwolla/errors/missing_parameter_error.rb +3 -3
  26. data/lib/dwolla/exceptions.rb +4 -4
  27. data/lib/dwolla/funding_sources.rb +65 -65
  28. data/lib/dwolla/json.rb +20 -20
  29. data/lib/dwolla/masspay.rb +52 -52
  30. data/lib/dwolla/oauth.rb +83 -75
  31. data/lib/dwolla/offsite_gateway.rb +152 -152
  32. data/lib/dwolla/requests.rb +56 -56
  33. data/lib/dwolla/transactions.rb +111 -56
  34. data/lib/dwolla/users.rb +39 -39
  35. data/lib/dwolla/version.rb +3 -3
  36. data/test/test_accounts.rb +18 -18
  37. data/test/test_balance.rb +9 -9
  38. data/test/test_contacts.rb +19 -19
  39. data/test/test_funding_sources.rb +64 -64
  40. data/test/test_masspay.rb +47 -47
  41. data/test/test_oauth.rb +36 -30
  42. data/test/test_offsite_gateway.rb +57 -57
  43. data/test/test_requests.rb +29 -29
  44. data/test/test_transactions.rb +117 -51
  45. data/test/test_users.rb +33 -33
  46. metadata +21 -21
data/lib/dwolla/oauth.rb CHANGED
@@ -1,76 +1,84 @@
1
- module Dwolla
2
- class OAuth
3
- def self.get_auth_url(redirect_uri=nil, scope=Dwolla::scope)
4
- raise AuthenticationError.new('No Api Key Provided.') unless Dwolla::api_key
5
-
6
- params = {
7
- :scope => scope,
8
- :response_type => 'code',
9
- :client_id => Dwolla::api_key
10
- }
11
-
12
- params['redirect_uri'] = redirect_uri unless redirect_uri.nil?
13
-
14
- uri = Addressable::URI.new
15
- uri.query_values = params
16
-
17
- if Dwolla::debug and Dwolla::sandbox
18
- puts "[DWOLLA SANDBOX MODE OPERATION]"
19
- end
20
-
21
- return auth_url + '?' + uri.query
22
- end
23
-
24
- def self.get_token(code=nil, redirect_uri=nil)
25
- raise MissingParameterError.new('No Code Provided.') if code.nil?
26
-
27
- params = {
28
- :grant_type => 'authorization_code',
29
- :code => code
30
- }
31
-
32
- # I realize this is ugly, but the unit tests fail
33
- # if the key is accessed["like_this"] because the
34
- # hash is compared with "quotes" and not :like_this.
35
-
36
- # It may very well be my Ruby version
37
- # TODO: Revisit this
38
- (params = params.merge({:redirect_uri => redirect_uri})) unless redirect_uri.nil?
39
-
40
- resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
41
-
42
- # TODO: Revisit this to make it more unit test friendly, fails ['error_description'] due to
43
- # key not existing, same on L58
44
- return "No data received." unless resp.is_a?(Hash)
45
- raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
46
-
47
- return resp
48
- end
49
-
50
- def self.refresh_auth(refresh_token=nil)
51
- raise MissingParameterError.new('No Refresh Token Provided') if refresh_token.nil?
52
-
53
- params = {
54
- :grant_type => 'refresh_token',
55
- :refresh_token => refresh_token
56
- }
57
-
58
- resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
59
-
60
- return "No data received." unless resp.is_a?(Hash)
61
- raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
62
-
63
- return resp
64
- end
65
-
66
- private
67
-
68
- def self.auth_url
69
- Dwolla.hostname + '/oauth/v2/authenticate'
70
- end
71
-
72
- def self.token_url
73
- Dwolla.hostname + '/oauth/v2/token'
74
- end
75
- end
1
+ module Dwolla
2
+ class OAuth
3
+ def self.get_auth_url(redirect_uri=nil, scope=Dwolla::scope)
4
+ raise AuthenticationError.new('No Api Key Provided.') unless Dwolla::api_key
5
+
6
+ params = {
7
+ :scope => scope,
8
+ :response_type => 'code',
9
+ :client_id => Dwolla::api_key
10
+ }
11
+
12
+ params['redirect_uri'] = redirect_uri unless redirect_uri.nil?
13
+
14
+ uri = Addressable::URI.new
15
+ uri.query_values = params
16
+
17
+ if Dwolla::debug and Dwolla::sandbox
18
+ puts "[DWOLLA SANDBOX MODE OPERATION]"
19
+ end
20
+
21
+ return auth_url + '?' + uri.query
22
+ end
23
+
24
+ def self.get_token(code=nil, redirect_uri=nil)
25
+ raise MissingParameterError.new('No Code Provided.') if code.nil?
26
+
27
+ params = {
28
+ :grant_type => 'authorization_code',
29
+ :code => code
30
+ }
31
+
32
+ # I realize this is ugly, but the unit tests fail
33
+ # if the key is accessed["like_this"] because the
34
+ # hash is compared with "quotes" and not :like_this.
35
+
36
+ # It may very well be my Ruby version
37
+ # TODO: Revisit this
38
+ (params = params.merge({:redirect_uri => redirect_uri})) unless redirect_uri.nil?
39
+
40
+ resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
41
+
42
+ # TODO: Revisit this to make it more unit test friendly, fails ['error_description'] due to
43
+ # key not existing, same on L58
44
+ return "No data received." unless resp.is_a?(Hash)
45
+ raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
46
+
47
+ return resp
48
+ end
49
+
50
+ def self.refresh_auth(refresh_token=nil)
51
+ raise MissingParameterError.new('No Refresh Token Provided') if refresh_token.nil?
52
+
53
+ params = {
54
+ :grant_type => 'refresh_token',
55
+ :refresh_token => refresh_token
56
+ }
57
+
58
+ resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
59
+
60
+ return "No data received." unless resp.is_a?(Hash)
61
+ raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
62
+
63
+ return resp
64
+ end
65
+
66
+ def self.catalog(token=nil)
67
+ resp = Dwolla.request(:get, '/catalog', {}, {}, token, false, false)
68
+
69
+ return "No data received." unless resp.is_a?(Hash)
70
+ raise APIError.new(resp['Message']) unless resp.has_key?('_links')
71
+ return resp['_links']
72
+ end
73
+
74
+ private
75
+
76
+ def self.auth_url
77
+ Dwolla.hostname + '/oauth/v2/authenticate'
78
+ end
79
+
80
+ def self.token_url
81
+ Dwolla.hostname + '/oauth/v2/token'
82
+ end
83
+ end
76
84
  end
@@ -1,152 +1,152 @@
1
- module Dwolla
2
- class OffsiteGateway
3
- @products = []
4
- @discount = 0
5
- @tax = 0
6
- @shipping = 0
7
- @notes = nil
8
- @facilitator_amount = nil
9
- @test_mode = false
10
- @allow_funding_sources = true
11
- @additional_funding_sources = true
12
- @order_id = nil
13
-
14
- def self.clear_session
15
- @products = []
16
- @discount = 0
17
- @tax = 0
18
- @shipping = 0
19
- @notes = nil
20
- @facilitator_amount = nil
21
- @test_mode = false
22
- @allow_funding_sources = true
23
- @additional_funding_sources = true
24
- @order_id = nil
25
- end
26
-
27
- class << self
28
- attr_writer :tax
29
- attr_writer :shipping
30
- attr_writer :notes
31
- attr_writer :order_id
32
- attr_writer :redirect
33
- attr_writer :callback
34
- attr_writer :test_mode
35
- attr_writer :allow_funding_sources
36
- attr_writer :additional_funding_sources
37
- attr_writer :facilitator_amount
38
- end
39
-
40
- def self.add_product(name=nil, description=nil, price=nil, quantity=1)
41
- @products.push({
42
- :name => name,
43
- :description => description,
44
- :price => price,
45
- :quantity => quantity
46
- })
47
- end
48
-
49
- def self.set_customer_info(first_name=nil, last_name=nil, email=nil, city=nil, state=nil, zip=nil)
50
- @customerInfo = {
51
- :firstName => first_name,
52
- :lastName => last_name,
53
- :email => email,
54
- :city => city,
55
- :state => state,
56
- :zip => zip
57
- }
58
- end
59
-
60
- def self.discount=(discount)
61
- @discount = -(discount.abs)
62
- end
63
-
64
- def self.get_checkout_url(destinationId)
65
- params = {
66
- :key => Dwolla::api_key,
67
- :secret => Dwolla::api_secret,
68
- :allowFundingSources => @allow_funding_sources,
69
- :additionalFundingSources => @additional_funding_sources,
70
- :test => @test_mode,
71
- :callback => @callback,
72
- :redirect => @redirect,
73
- :orderId => @order_id,
74
- :notes => @notes,
75
- :purchaseOrder => {
76
- :customerInfo => @customerInfo,
77
- :destinationId => destinationId,
78
- :orderItems => @products,
79
- :facilitatorAmount => @facilitator_amount,
80
- :discount => @discount,
81
- :shipping => @shipping,
82
- :tax => @tax,
83
- :total => self.calculate_total
84
- }
85
- }
86
-
87
- resp = Dwolla.request(:post, request_url, params, {}, false, false, true)
88
-
89
- return "No data received." unless resp.is_a?(Hash)
90
- raise APIError.new(resp['Message']) unless resp.has_key?('Result') and resp['Result'] == 'Success'
91
-
92
- return checkout_url + resp['CheckoutId']
93
- end
94
-
95
- def self.read_callback(body)
96
- data = JSON.load(body)
97
- verify_callback_signature(data['signature'], data['checkoutId'], data['amount'])
98
-
99
- return data
100
- end
101
-
102
- def self.validate_webhook(signature, body)
103
- verify_webhook_signature(signature, body)
104
- end
105
-
106
- private
107
- def self.verify_callback_signature(candidate=nil, checkout_id=nil, amount=nil)
108
- key = "#{checkout_id}&#{amount}"
109
- digest = OpenSSL::Digest.new('sha1')
110
- signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, key)
111
-
112
- raise APIError.new("Invalid callback signature (#{candidate} vs #{signature})") unless candidate == signature
113
- end
114
-
115
- def self.verify_webhook_signature(candidate=nil, body=nil)
116
- digest = OpenSSL::Digest.new('sha1')
117
- signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, body)
118
-
119
- raise APIError.new("Invalid Webhook signature (#{candidate} vs #{signature})") unless candidate == signature
120
- end
121
-
122
- def self.request_url
123
- if Dwolla::sandbox
124
- return 'https://uat.dwolla.com/payment/request'
125
- else
126
- return 'https://www.dwolla.com/payment/request'
127
- end
128
- end
129
-
130
- def self.checkout_url
131
- if Dwolla::sandbox
132
- return 'https://uat.dwolla.com/payment/checkout/'
133
- else
134
- return 'https://www.dwolla.com/payment/checkout/'
135
- end
136
- end
137
-
138
- def self.calculate_total
139
- total = 0.0
140
-
141
- @products.each { |product|
142
- total += product[:price] * product[:quantity]
143
- }
144
-
145
- total += @shipping
146
- total += @tax
147
- total += @discount
148
-
149
- return total.round(2)
150
- end
151
- end
152
- end
1
+ module Dwolla
2
+ class OffsiteGateway
3
+ @products = []
4
+ @discount = 0
5
+ @tax = 0
6
+ @shipping = 0
7
+ @notes = nil
8
+ @facilitator_amount = nil
9
+ @test_mode = false
10
+ @allow_funding_sources = true
11
+ @additional_funding_sources = true
12
+ @order_id = nil
13
+
14
+ def self.clear_session
15
+ @products = []
16
+ @discount = 0
17
+ @tax = 0
18
+ @shipping = 0
19
+ @notes = nil
20
+ @facilitator_amount = nil
21
+ @test_mode = false
22
+ @allow_funding_sources = true
23
+ @additional_funding_sources = true
24
+ @order_id = nil
25
+ end
26
+
27
+ class << self
28
+ attr_writer :tax
29
+ attr_writer :shipping
30
+ attr_writer :notes
31
+ attr_writer :order_id
32
+ attr_writer :redirect
33
+ attr_writer :callback
34
+ attr_writer :test_mode
35
+ attr_writer :allow_funding_sources
36
+ attr_writer :additional_funding_sources
37
+ attr_writer :facilitator_amount
38
+ end
39
+
40
+ def self.add_product(name=nil, description=nil, price=nil, quantity=1)
41
+ @products.push({
42
+ :name => name,
43
+ :description => description,
44
+ :price => price,
45
+ :quantity => quantity
46
+ })
47
+ end
48
+
49
+ def self.set_customer_info(first_name=nil, last_name=nil, email=nil, city=nil, state=nil, zip=nil)
50
+ @customerInfo = {
51
+ :firstName => first_name,
52
+ :lastName => last_name,
53
+ :email => email,
54
+ :city => city,
55
+ :state => state,
56
+ :zip => zip
57
+ }
58
+ end
59
+
60
+ def self.discount=(discount)
61
+ @discount = -(discount.abs)
62
+ end
63
+
64
+ def self.get_checkout_url(destinationId)
65
+ params = {
66
+ :key => Dwolla::api_key,
67
+ :secret => Dwolla::api_secret,
68
+ :allowFundingSources => @allow_funding_sources,
69
+ :additionalFundingSources => @additional_funding_sources,
70
+ :test => @test_mode,
71
+ :callback => @callback,
72
+ :redirect => @redirect,
73
+ :orderId => @order_id,
74
+ :notes => @notes,
75
+ :purchaseOrder => {
76
+ :customerInfo => @customerInfo,
77
+ :destinationId => destinationId,
78
+ :orderItems => @products,
79
+ :facilitatorAmount => @facilitator_amount,
80
+ :discount => @discount,
81
+ :shipping => @shipping,
82
+ :tax => @tax,
83
+ :total => self.calculate_total
84
+ }
85
+ }
86
+
87
+ resp = Dwolla.request(:post, request_url, params, {}, false, false, true)
88
+
89
+ return "No data received." unless resp.is_a?(Hash)
90
+ raise APIError.new(resp['Message']) unless resp.has_key?('Result') and resp['Result'] == 'Success'
91
+
92
+ return checkout_url + resp['CheckoutId']
93
+ end
94
+
95
+ def self.read_callback(body)
96
+ data = JSON.load(body)
97
+ verify_callback_signature(data['signature'], data['checkoutId'], data['amount'])
98
+
99
+ return data
100
+ end
101
+
102
+ def self.validate_webhook(signature, body)
103
+ verify_webhook_signature(signature, body)
104
+ end
105
+
106
+ private
107
+ def self.verify_callback_signature(candidate=nil, checkout_id=nil, amount=nil)
108
+ key = "#{checkout_id}&#{amount}"
109
+ digest = OpenSSL::Digest.new('sha1')
110
+ signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, key)
111
+
112
+ raise APIError.new("Invalid callback signature (#{candidate} vs #{signature})") unless candidate == signature
113
+ end
114
+
115
+ def self.verify_webhook_signature(candidate=nil, body=nil)
116
+ digest = OpenSSL::Digest.new('sha1')
117
+ signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, body)
118
+
119
+ raise APIError.new("Invalid Webhook signature (#{candidate} vs #{signature})") unless candidate == signature
120
+ end
121
+
122
+ def self.request_url
123
+ if Dwolla::sandbox
124
+ return 'https://uat.dwolla.com/payment/request'
125
+ else
126
+ return 'https://www.dwolla.com/payment/request'
127
+ end
128
+ end
129
+
130
+ def self.checkout_url
131
+ if Dwolla::sandbox
132
+ return 'https://uat.dwolla.com/payment/checkout/'
133
+ else
134
+ return 'https://www.dwolla.com/payment/checkout/'
135
+ end
136
+ end
137
+
138
+ def self.calculate_total
139
+ total = 0.0
140
+
141
+ @products.each { |product|
142
+ total += product[:price] * product[:quantity]
143
+ }
144
+
145
+ total += @shipping
146
+ total += @tax
147
+ total += @discount
148
+
149
+ return total.round(2)
150
+ end
151
+ end
152
+ end