dwolla-ruby 2.1.1 → 2.2.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDlhOWUxN2FiMzIxOWEwNDAzNjIzMTU5YTIxZjEwNjZlZDJhOGIyMQ==
5
+ data.tar.gz: !binary |-
6
+ NGY1NzEzYWU4ZWU3MWNmOTE5OThhZGNhMTY4ZjIxZGI5MWZiYWQxNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NWQ0YTFjY2YwYzM0YTM0MDBkNjM5NWExNTY1MGRjZTBmNDdhNDI1ZGExNDJh
10
+ NGYyNDE2NjEzZTVjMjA5ZjRlZDMxNWUzMzcxY2MwM2U2ZjliOWVkNWFhOWEy
11
+ NGI0NDJhYWZkZDgwNTU5NTlkMTZlMmU3NzIyZWMxZmI5MDQ1MGI=
12
+ data.tar.gz: !binary |-
13
+ NWU4ZTAwNGNkN2JjMGIzY2Q4NWI4MWViNjNlNzRhY2ZkYThjZDBiZTczMjU5
14
+ Zjc4NDE5ODg1ZDdhODg5MzY5YTk3MmU2M2NlNDdmNzMzNjhiZDljM2RhMjhi
15
+ YzFmNDQzNDI5ZTExOTUxOGIzZDM4YjlkZDkzYjg3YmIxNzdkMGE=
@@ -1 +1,34 @@
1
- # Coming soon...
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ # Include the Dwolla gem
4
+ require 'rubygems'
5
+ require 'pp'
6
+ require '../lib/dwolla'
7
+
8
+ # Include any required keys
9
+ require './_keys.rb'
10
+
11
+ # Instantiate a new Dwolla User client
12
+ Dwolla::api_key = @api_key
13
+ Dwolla::api_secret = @api_secret
14
+ Dwolla::debug = false
15
+
16
+ # Clear out any previous session data
17
+ Dwolla::OffsiteGateway.clear_session
18
+
19
+ # Optional Settings
20
+ Dwolla::OffsiteGateway.redirect = 'http://dwolla.com/payment_redirect'
21
+ Dwolla::OffsiteGateway.callback = 'http://dwolla.com/payment_callback'
22
+ Dwolla::OffsiteGateway.set_customer_info('Michael', 'Schonfeld', 'michael@dwolla.com', 'New York', 'NY', '10001')
23
+ Dwolla::OffsiteGateway.discount = 4.95
24
+ Dwolla::OffsiteGateway.notes = 'This is just an offsite gateway test...'
25
+
26
+ # Add products
27
+ Dwolla::OffsiteGateway.add_product('Macbook Air', '13" Macbook Air; Model #0001', 499.99, 1)
28
+
29
+ # Generate a checkout sesssion
30
+ pp Dwolla::OffsiteGateway.get_checkout_url('812-734-7288')
31
+
32
+ # Verify and parse gateway callback
33
+ data = Dwolla::OffsiteGateway.read_callback('{"Amount":0.01,"OrderId":null,"Status":"Completed","Error":null,"TransactionId":3396300,"CheckoutId":"51f9dfaa-20ed-41a7-8874-00a47c19c655","Signature":"8be03dfd0e95c567b2855f5876acfc98992f6402","TestMode":"false","ClearingDate":"7/22/2013 8:42:18 PM"}')
34
+ pp data
data/lib/dwolla.rb CHANGED
@@ -18,7 +18,7 @@ require 'dwolla/users'
18
18
  require 'dwolla/balance'
19
19
  require 'dwolla/funding_sources'
20
20
  require 'dwolla/oauth'
21
- # require 'dwolla/offsite_gateway' // Needs more work
21
+ require 'dwolla/offsite_gateway'
22
22
 
23
23
  # Errors
24
24
  require 'dwolla/errors/dwolla_error'
@@ -4,56 +4,117 @@ module Dwolla
4
4
  @discount = 0
5
5
  @tax = 0
6
6
  @shipping = 0
7
- @destination_id = nil
8
7
  @notes = nil
9
8
  @facilitatorAmount = nil
9
+ @testMode = false
10
+ @allowFundingSources = true
10
11
 
11
12
  def self.clear_session
12
13
  @products = []
13
14
  end
14
15
 
15
16
  def self.add_product(name=nil, description=nil, price=nil, quantity=1)
16
- @products.push {
17
+ @products.push({
17
18
  :name => name,
18
19
  :description => description,
19
20
  :price => price,
20
21
  :quantity => quantity
22
+ })
23
+ end
24
+
25
+ def self.set_customer_info(first_name=nil, last_name=nil, email=nil, city=nil, state=nil, zip=nil)
26
+ @customerInfo = {
27
+ :firstName => first_name,
28
+ :lastName => last_name,
29
+ :email => email,
30
+ :city => city,
31
+ :state => state,
32
+ :zip => zip
21
33
  }
22
34
  end
23
35
 
24
36
  def self.discount=(discount)
25
- @discount = discount
37
+ @discount = -(discount.abs).to_i
26
38
  end
27
39
 
28
40
  def self.tax=(tax)
29
- @tax = tax
41
+ @tax = tax.to_i
30
42
  end
31
43
 
32
44
  def self.shipping=(shipping)
33
- @shipping = shipping
45
+ @shipping = shipping.to_i
46
+ end
47
+
48
+ def self.notes=(notes)
49
+ @notes = notes
50
+ end
51
+
52
+ def self.redirect=(redirect)
53
+ @redirect = redirect
34
54
  end
35
55
 
36
- def self.get_checkout_url(params={})
56
+ def self.callback=(callback)
57
+ @callback = callback
58
+ end
59
+
60
+ def self.test=(test)
61
+ @testMode = test
62
+ end
63
+
64
+ def self.get_checkout_url(destinationId)
37
65
  params = {
38
66
  :key => Dwolla::api_key,
39
67
  :secret => Dwolla::api_secret,
68
+ :allowFundingSources => @allowFundingSources,
69
+ :test => @testMode,
70
+ :callback => @callback,
71
+ :redirect => @redirect,
40
72
  :purchaseOrder => {
41
- :destinationId => @destinationId,
73
+ :customerInfo => @customerInfo,
74
+ :destinationId => destinationId,
42
75
  :orderItems => @products,
43
76
  :discount => @discount,
44
77
  :shipping => @shipping,
45
78
  :tax => @tax,
46
- :total => @total
79
+ :total => self.calculate_total
47
80
  }
48
81
  }
49
82
 
50
- resp = Dwolla.request(:post, request_url, params, {}, false, false)
83
+ resp = Dwolla.request(:post, request_url, params, {}, false, false, true)
84
+ raise APIError.new(resp['Message']) unless resp['Result'] == 'Success'
51
85
 
52
86
  return checkout_url + resp['CheckoutId']
53
87
  end
54
88
 
89
+ def self.read_callback(body)
90
+ data = JSON.load(body)
91
+
92
+ verify_callback_signature(data['Signature'], data['CheckoutId'], data['Amount'])
93
+
94
+ return data
95
+ end
96
+
97
+ def self.verify_webhook_signature(body, signature)
98
+ verify_webhook_signature(signature, body)
99
+ end
100
+
55
101
  private
56
102
 
103
+ def self.verify_callback_signature(candidate=nil, checkout_id=nil, amount=nil)
104
+ key = "#{checkout_id}&#{amount}"
105
+ digest = OpenSSL::Digest::Digest.new('sha1')
106
+ signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, key)
107
+
108
+ raise APIError.new("Invalid callback signature (#{candidate} vs #{signature})") unless candidate == signature
109
+ end
110
+
111
+ def self.verify_webhook_signature(candidate=nil, body=nil)
112
+ digest = OpenSSL::Digest::Digest.new('sha1')
113
+ signature = OpenSSL::HMAC.hexdigest(digest, Dwolla::api_secret, body)
114
+
115
+ raise APIError.new("Invalid Webhook signature (#{candidate} vs #{signature})") unless candidate == signature
116
+ end
117
+
57
118
  def self.request_url
58
119
  return 'https://www.dwolla.com/payment/request'
59
120
  end
@@ -63,14 +124,17 @@ module Dwolla
63
124
  end
64
125
 
65
126
  def self.calculate_total
66
- @total = 0
127
+ total = 0
67
128
 
68
129
  @products.each { |product|
69
- @total += product['price'] * product['quantity']
130
+ total += product[:price] * product[:quantity]
70
131
  }
71
132
 
72
- return @total
73
- end
133
+ total += @shipping
134
+ total += @tax
135
+ total += @discount
74
136
 
137
+ return total
138
+ end
75
139
  end
76
140
  end
@@ -1,3 +1,3 @@
1
1
  module Dwolla
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.1"
3
3
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dwolla-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
5
- prerelease:
4
+ version: 2.2.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michael Schonfeld
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-06-07 00:00:00.000000000 Z
11
+ date: 2013-07-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rest-client
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: multi_json
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -41,7 +37,6 @@ dependencies:
41
37
  type: :runtime
42
38
  prerelease: false
43
39
  version_requirements: !ruby/object:Gem::Requirement
44
- none: false
45
40
  requirements:
46
41
  - - ! '>='
47
42
  - !ruby/object:Gem::Version
@@ -52,7 +47,6 @@ dependencies:
52
47
  - !ruby/object:Gem::Dependency
53
48
  name: addressable
54
49
  requirement: !ruby/object:Gem::Requirement
55
- none: false
56
50
  requirements:
57
51
  - - ! '>='
58
52
  - !ruby/object:Gem::Version
@@ -60,7 +54,6 @@ dependencies:
60
54
  type: :runtime
61
55
  prerelease: false
62
56
  version_requirements: !ruby/object:Gem::Requirement
63
- none: false
64
57
  requirements:
65
58
  - - ! '>='
66
59
  - !ruby/object:Gem::Version
@@ -68,7 +61,6 @@ dependencies:
68
61
  - !ruby/object:Gem::Dependency
69
62
  name: mocha
70
63
  requirement: !ruby/object:Gem::Requirement
71
- none: false
72
64
  requirements:
73
65
  - - ! '>='
74
66
  - !ruby/object:Gem::Version
@@ -76,7 +68,6 @@ dependencies:
76
68
  type: :development
77
69
  prerelease: false
78
70
  version_requirements: !ruby/object:Gem::Requirement
79
- none: false
80
71
  requirements:
81
72
  - - ! '>='
82
73
  - !ruby/object:Gem::Version
@@ -84,7 +75,6 @@ dependencies:
84
75
  - !ruby/object:Gem::Dependency
85
76
  name: shoulda
86
77
  requirement: !ruby/object:Gem::Requirement
87
- none: false
88
78
  requirements:
89
79
  - - ! '>='
90
80
  - !ruby/object:Gem::Version
@@ -92,7 +82,6 @@ dependencies:
92
82
  type: :development
93
83
  prerelease: false
94
84
  version_requirements: !ruby/object:Gem::Requirement
95
- none: false
96
85
  requirements:
97
86
  - - ! '>='
98
87
  - !ruby/object:Gem::Version
@@ -100,7 +89,6 @@ dependencies:
100
89
  - !ruby/object:Gem::Dependency
101
90
  name: test-unit
102
91
  requirement: !ruby/object:Gem::Requirement
103
- none: false
104
92
  requirements:
105
93
  - - ! '>='
106
94
  - !ruby/object:Gem::Version
@@ -108,7 +96,6 @@ dependencies:
108
96
  type: :development
109
97
  prerelease: false
110
98
  version_requirements: !ruby/object:Gem::Requirement
111
- none: false
112
99
  requirements:
113
100
  - - ! '>='
114
101
  - !ruby/object:Gem::Version
@@ -116,7 +103,6 @@ dependencies:
116
103
  - !ruby/object:Gem::Dependency
117
104
  name: rake
118
105
  requirement: !ruby/object:Gem::Requirement
119
- none: false
120
106
  requirements:
121
107
  - - ! '>='
122
108
  - !ruby/object:Gem::Version
@@ -124,7 +110,6 @@ dependencies:
124
110
  type: :development
125
111
  prerelease: false
126
112
  version_requirements: !ruby/object:Gem::Requirement
127
- none: false
128
113
  requirements:
129
114
  - - ! '>='
130
115
  - !ruby/object:Gem::Version
@@ -174,27 +159,26 @@ files:
174
159
  - test/test_helper.rb
175
160
  homepage: https://github.com/dwolla/dwolla-ruby
176
161
  licenses: []
162
+ metadata: {}
177
163
  post_install_message:
178
164
  rdoc_options: []
179
165
  require_paths:
180
166
  - lib
181
167
  required_ruby_version: !ruby/object:Gem::Requirement
182
- none: false
183
168
  requirements:
184
169
  - - ! '>='
185
170
  - !ruby/object:Gem::Version
186
171
  version: '0'
187
172
  required_rubygems_version: !ruby/object:Gem::Requirement
188
- none: false
189
173
  requirements:
190
174
  - - ! '>='
191
175
  - !ruby/object:Gem::Version
192
176
  version: '0'
193
177
  requirements: []
194
178
  rubyforge_project: dwolla-ruby
195
- rubygems_version: 1.8.24
179
+ rubygems_version: 2.0.5
196
180
  signing_key:
197
- specification_version: 3
181
+ specification_version: 4
198
182
  summary: Official Ruby Wrapper for Dwolla's API
199
183
  test_files:
200
184
  - test/test_dwolla.rb