dwolla-ruby 2.9.0 → 3.0.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -8
  3. data/.travis.yml +11 -6
  4. data/Gemfile +1 -1
  5. data/README.md +225 -222
  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 -59
  12. data/examples/offsiteGateway.rb +31 -31
  13. data/examples/transactions.rb +72 -72
  14. data/examples/users.rb +30 -30
  15. data/gemfiles/json.gemfile +2 -2
  16. data/lib/dwolla.rb +319 -327
  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 +84 -84
  31. data/lib/dwolla/offsite_gateway.rb +152 -152
  32. data/lib/dwolla/requests.rb +56 -56
  33. data/lib/dwolla/transactions.rb +108 -108
  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_dwolla.rb +62 -0
  40. data/test/test_funding_sources.rb +64 -64
  41. data/test/test_masspay.rb +47 -47
  42. data/test/test_oauth.rb +36 -36
  43. data/test/test_offsite_gateway.rb +57 -57
  44. data/test/test_requests.rb +29 -29
  45. data/test/test_transactions.rb +117 -117
  46. data/test/test_users.rb +33 -33
  47. metadata +5 -3
@@ -1,85 +1,85 @@
1
- module Dwolla
2
- class OAuth
3
- def self.get_auth_url(redirect_uri=nil, scope=Dwolla::scope, verified_account=false)
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
- :verified_account => verified_account
11
- }
12
-
13
- params['redirect_uri'] = redirect_uri unless redirect_uri.nil?
14
-
15
- uri = Addressable::URI.new
16
- uri.query_values = params
17
-
18
- if Dwolla::debug and Dwolla::sandbox
19
- puts "[DWOLLA SANDBOX MODE OPERATION]"
20
- end
21
-
22
- return auth_url + '?' + uri.query
23
- end
24
-
25
- def self.get_token(code=nil, redirect_uri=nil)
26
- raise MissingParameterError.new('No Code Provided.') if code.nil?
27
-
28
- params = {
29
- :grant_type => 'authorization_code',
30
- :code => code
31
- }
32
-
33
- # I realize this is ugly, but the unit tests fail
34
- # if the key is accessed["like_this"] because the
35
- # hash is compared with "quotes" and not :like_this.
36
-
37
- # It may very well be my Ruby version
38
- # TODO: Revisit this
39
- (params = params.merge({:redirect_uri => redirect_uri})) unless redirect_uri.nil?
40
-
41
- resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
42
-
43
- # TODO: Revisit this to make it more unit test friendly, fails ['error_description'] due to
44
- # key not existing, same on L58
45
- return "No data received." unless resp.is_a?(Hash)
46
- raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
47
-
48
- return resp
49
- end
50
-
51
- def self.refresh_auth(refresh_token=nil)
52
- raise MissingParameterError.new('No Refresh Token Provided') if refresh_token.nil?
53
-
54
- params = {
55
- :grant_type => 'refresh_token',
56
- :refresh_token => refresh_token
57
- }
58
-
59
- resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
60
-
61
- return "No data received." unless resp.is_a?(Hash)
62
- raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
63
-
64
- return resp
65
- end
66
-
67
- def self.catalog(token=nil)
68
- resp = Dwolla.request(:get, '/catalog', {}, {}, token, false, false)
69
-
70
- return "No data received." unless resp.is_a?(Hash)
71
- raise APIError.new(resp['Message']) unless resp.has_key?('_links')
72
- return resp['_links']
73
- end
74
-
75
- private
76
-
77
- def self.auth_url
78
- Dwolla.hostname + '/oauth/v2/authenticate'
79
- end
80
-
81
- def self.token_url
82
- Dwolla.hostname + '/oauth/v2/token'
83
- end
84
- end
1
+ module Dwolla
2
+ class OAuth
3
+ def self.get_auth_url(redirect_uri=nil, scope=Dwolla::scope, verified_account=false)
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
+ :verified_account => verified_account
11
+ }
12
+
13
+ params['redirect_uri'] = redirect_uri unless redirect_uri.nil?
14
+
15
+ uri = Addressable::URI.new
16
+ uri.query_values = params
17
+
18
+ if Dwolla::debug and Dwolla::sandbox
19
+ puts "[DWOLLA SANDBOX MODE OPERATION]"
20
+ end
21
+
22
+ return auth_url + '?' + uri.query
23
+ end
24
+
25
+ def self.get_token(code=nil, redirect_uri=nil)
26
+ raise MissingParameterError.new('No Code Provided.') if code.nil?
27
+
28
+ params = {
29
+ :grant_type => 'authorization_code',
30
+ :code => code
31
+ }
32
+
33
+ # I realize this is ugly, but the unit tests fail
34
+ # if the key is accessed["like_this"] because the
35
+ # hash is compared with "quotes" and not :like_this.
36
+
37
+ # It may very well be my Ruby version
38
+ # TODO: Revisit this
39
+ (params = params.merge({:redirect_uri => redirect_uri})) unless redirect_uri.nil?
40
+
41
+ resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
42
+
43
+ # TODO: Revisit this to make it more unit test friendly, fails ['error_description'] due to
44
+ # key not existing, same on L58
45
+ return "No data received." unless resp.is_a?(Hash)
46
+ raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
47
+
48
+ return resp
49
+ end
50
+
51
+ def self.refresh_auth(refresh_token=nil)
52
+ raise MissingParameterError.new('No Refresh Token Provided') if refresh_token.nil?
53
+
54
+ params = {
55
+ :grant_type => 'refresh_token',
56
+ :refresh_token => refresh_token
57
+ }
58
+
59
+ resp = Dwolla.request(:post, token_url, params, {}, false, false, true)
60
+
61
+ return "No data received." unless resp.is_a?(Hash)
62
+ raise APIError.new(resp['error_description']) unless resp.has_key?('access_token') and resp.has_key?('refresh_token')
63
+
64
+ return resp
65
+ end
66
+
67
+ def self.catalog(token=nil)
68
+ resp = Dwolla.request(:get, '/catalog', {}, {}, token, false, false)
69
+
70
+ return "No data received." unless resp.is_a?(Hash)
71
+ raise APIError.new(resp['Message']) unless resp.has_key?('_links')
72
+ return resp['_links']
73
+ end
74
+
75
+ private
76
+
77
+ def self.auth_url
78
+ Dwolla.hostname + '/oauth/v2/authenticate'
79
+ end
80
+
81
+ def self.token_url
82
+ Dwolla.hostname + '/oauth/v2/token'
83
+ end
84
+ end
85
85
  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://sandbox.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://sandbox.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