dwolla-ruby 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/README.md +130 -0
- data/Rakefile +5 -0
- data/dwolla.gemspec +29 -0
- data/examples/_keys.rb +5 -0
- data/examples/accountInfo.rb +31 -0
- data/examples/contacts.rb +27 -0
- data/examples/fundingSources.rb +26 -0
- data/examples/oauth.rb +35 -0
- data/examples/offsiteGateway.rb +1 -0
- data/examples/send.rb +23 -0
- data/lib/dwolla.rb +43 -0
- data/lib/dwolla/client.rb +50 -0
- data/lib/dwolla/connection.rb +47 -0
- data/lib/dwolla/exceptions.rb +4 -0
- data/lib/dwolla/funding_source.rb +18 -0
- data/lib/dwolla/response/follow_redirects.rb +44 -0
- data/lib/dwolla/response/guard_server_error.rb +32 -0
- data/lib/dwolla/response/parse_json.rb +27 -0
- data/lib/dwolla/transaction.rb +55 -0
- data/lib/dwolla/user.rb +98 -0
- data/lib/dwolla/version.rb +3 -0
- data/spec/dwolla/client_spec.rb +27 -0
- data/spec/dwolla/response/follow_redirects_spec.rb +38 -0
- data/spec/dwolla/transaction_spec.rb +181 -0
- data/spec/dwolla/user_spec.rb +260 -0
- data/spec/dwolla_spec.rb +19 -0
- data/spec/fixtures/account_information.json +13 -0
- data/spec/fixtures/balance.json +5 -0
- data/spec/fixtures/basic_information.json +6 -0
- data/spec/fixtures/contacts.json +18 -0
- data/spec/fixtures/error.json +5 -0
- data/spec/fixtures/request_transaction.json +3 -0
- data/spec/fixtures/send_transaction.json +3 -0
- data/spec/fixtures/sources.json +13 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/helpers.rb +29 -0
- metadata +212 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# dwolla-ruby: Ruby Wrapper for Dwolla's API
|
2
|
+
=================================================================================
|
3
|
+
|
4
|
+
## Version
|
5
|
+
1.0.0
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
- [Ruby](http://www.ruby-lang.org/)
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
The recommended way to install dwolla-php is through RubyGems:
|
13
|
+
|
14
|
+
gem install dwolla-ruby
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
```ruby
|
18
|
+
|
19
|
+
```
|
20
|
+
|
21
|
+
## Examples / Quickstart
|
22
|
+
|
23
|
+
This repo includes various usage examples, including:
|
24
|
+
|
25
|
+
* Authenticating with OAuth [oauth.rb]
|
26
|
+
* Sending money [send.rb]
|
27
|
+
* Fetching account information [accountInfo.rb]
|
28
|
+
* Grabbing a user's contacts [contacts.rb]
|
29
|
+
* Listing a user's funding sources [fundingSources.rb]
|
30
|
+
* Creating offsite gateway sessions [offsiteGateway.rb]
|
31
|
+
|
32
|
+
## Methods
|
33
|
+
|
34
|
+
Authentication Methods:
|
35
|
+
|
36
|
+
getAuthUrl() ==> (string) OAuth permissions page URL
|
37
|
+
requestToken($code) ==> (string) a never-expiring OAuth access token
|
38
|
+
setToken($token) ==> (bool) was token saved?
|
39
|
+
getToken() ==> (string) current OAuth token
|
40
|
+
|
41
|
+
Users Methods:
|
42
|
+
|
43
|
+
me() ==> (array) the user entity associated with the token
|
44
|
+
getUser($user_id) ==> (array) the user entity for {$user_id}
|
45
|
+
|
46
|
+
Register Methods:
|
47
|
+
|
48
|
+
register($email, $password, $pin, $firstName, $lastName, $address, $address2, $city, $state, $zip, $phone, $dateOfBirth, $acceptTerms[, $type, $organization, $ein]) ==> (array) the newly created user record
|
49
|
+
|
50
|
+
Contacts Methods:
|
51
|
+
|
52
|
+
contacts([$search, $types, $limit]) ==> (array) list of contacts matching the search criteria
|
53
|
+
nearbyContacts([$search, $types, $limit]) ==> (array) list of nearby spots matching the search criteria
|
54
|
+
|
55
|
+
Funding Sources Methods:
|
56
|
+
|
57
|
+
fundingSources() ==> (array) a list of funding sources associated with the token
|
58
|
+
fundingSource($id) ==> (array) information about the {$id} funding source
|
59
|
+
|
60
|
+
Balance Methods:
|
61
|
+
|
62
|
+
balance() ==> (string) the Dwolla balance of the account associated with the token
|
63
|
+
|
64
|
+
Transactions Methods:
|
65
|
+
|
66
|
+
send($pin, $destinationId, $amount[, $destinationType, $notes, $facilitatorAmount, $assumeCosts]) ==> (string) transaction ID
|
67
|
+
request($pin, $sourceId, $amount[, $sourceType, $notes, $facilitatorAmount]) ==> (string) request ID
|
68
|
+
transaction($transactionId) ==> (array) transaction details
|
69
|
+
listings([$sinceDate, $types, $limit, $skip]) ==> (array) a list of recent transactions matching the search criteria
|
70
|
+
stats([$types, $sinceDate, $endDate]) ==> (array) statistics about the account associated with the token
|
71
|
+
|
72
|
+
Offsite Gateway Methods:
|
73
|
+
|
74
|
+
startGatewaySession() ==> (bool) did session start?
|
75
|
+
addGatewayProduct($name, $amount[, $quantity, $description]) ==> (bool) was product added?
|
76
|
+
verifyGatewaySignature($signature, $checkoutId, $amount) ==> (bool) is signature valid?
|
77
|
+
getGatewayURL($destinationId[, $orderId, $discount, $shipping, $tax, $notes, $callback]) ==> (string) checkout URL
|
78
|
+
|
79
|
+
Helper Methods:
|
80
|
+
|
81
|
+
getError() ==> (string) error message
|
82
|
+
parseDwollaID($id) ==> (bool) is valid Dwolla ID?
|
83
|
+
setMode($mode) ==> (bool) did mode change?
|
84
|
+
|
85
|
+
## Changelog
|
86
|
+
|
87
|
+
1.0.0
|
88
|
+
|
89
|
+
* Reworked Gem.
|
90
|
+
|
91
|
+
## Credits
|
92
|
+
|
93
|
+
This wrapper is a forked extension of Jefferson Girao's <@jeffersongirao> 'dwolla' module.
|
94
|
+
|
95
|
+
- Jefferson Gir�o <contato@jefferson.eti.br>
|
96
|
+
- Michael Schonfeld <michael@dwolla.com>
|
97
|
+
|
98
|
+
## Support
|
99
|
+
|
100
|
+
- Dwolla API <api@dwolla.com>
|
101
|
+
- Michael Schonfeld <michael@dwolla.com>
|
102
|
+
|
103
|
+
## References / Documentation
|
104
|
+
|
105
|
+
http://developers.dwolla.com/dev
|
106
|
+
|
107
|
+
## License
|
108
|
+
|
109
|
+
(The MIT License)
|
110
|
+
|
111
|
+
Copyright (c) 2012 Dwolla <michael@dwolla.com>
|
112
|
+
|
113
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
114
|
+
a copy of this software and associated documentation files (the
|
115
|
+
'Software'), to deal in the Software without restriction, including
|
116
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
117
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
118
|
+
permit persons to whom the Software is furnished to do so, subject to
|
119
|
+
the following conditions:
|
120
|
+
|
121
|
+
The above copyright notice and this permission notice shall be
|
122
|
+
included in all copies or substantial portions of the Software.
|
123
|
+
|
124
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
125
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
126
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
127
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
128
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
129
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
130
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/dwolla.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dwolla/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dwolla-ruby"
|
7
|
+
s.version = Dwolla::VERSION
|
8
|
+
s.authors = ["Jefferson Girao", "Michael Schonfeld"]
|
9
|
+
s.email = ["contato@jefferson.eti.br", "michael@dwolla.com"]
|
10
|
+
s.homepage = "https://github.com/dwolla/dwolla-ruby"
|
11
|
+
s.summary = %q{Official Ruby Wrapper for Dwolla's API}
|
12
|
+
s.description = %q{Official Ruby Wrapper for Dwolla's API}
|
13
|
+
|
14
|
+
s.rubyforge_project = "dwolla"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_dependency 'faraday', '= 0.7.6'
|
22
|
+
s.add_dependency 'multi_json', '= 1.3.6'
|
23
|
+
|
24
|
+
s.add_development_dependency 'bundler'
|
25
|
+
s.add_development_dependency 'rake'
|
26
|
+
s.add_development_dependency 'rspec'
|
27
|
+
s.add_development_dependency 'webmock'
|
28
|
+
s.add_development_dependency 'simplecov'
|
29
|
+
end
|
data/examples/_keys.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Include the Dwolla gem
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pp'
|
4
|
+
require 'dwolla'
|
5
|
+
|
6
|
+
# Include any required keys
|
7
|
+
require '_keys.rb'
|
8
|
+
|
9
|
+
# Instantiate a new Dwolla User client
|
10
|
+
# And, Sseed a previously generated access token
|
11
|
+
DwollaClient = Dwolla::Client.new($apiKey, $apiSecret)
|
12
|
+
DwollaUser = Dwolla::User.me($token)
|
13
|
+
|
14
|
+
|
15
|
+
# EXAMPLE 1:
|
16
|
+
# Fetch account information for the
|
17
|
+
# account associated with the provided
|
18
|
+
# OAuth token
|
19
|
+
pp DwollaUser.fetch
|
20
|
+
|
21
|
+
|
22
|
+
# EXAMPLE 2:
|
23
|
+
# Fetch basic account information
|
24
|
+
# for a given Dwolla ID
|
25
|
+
pp DwollaClient.user('812-626-8794')
|
26
|
+
|
27
|
+
|
28
|
+
# EXAMPLE 3:
|
29
|
+
# Fetch basic account information
|
30
|
+
# for a given Email address
|
31
|
+
pp DwollaClient.user('michael@dwolla.com')
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Include the Dwolla gem
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pp'
|
4
|
+
require 'dwolla'
|
5
|
+
|
6
|
+
# Include any required keys
|
7
|
+
require '_keys.rb'
|
8
|
+
|
9
|
+
# Instantiate a new Dwolla User client
|
10
|
+
# And, Sseed a previously generated access token
|
11
|
+
DwollaUser = Dwolla::User.me($token)
|
12
|
+
|
13
|
+
|
14
|
+
# EXAMPLE 1:
|
15
|
+
# Fetch last 10 contacts from the
|
16
|
+
# account associated with the provided
|
17
|
+
# OAuth token
|
18
|
+
contacts = DwollaUser.contacts()
|
19
|
+
pp contacts
|
20
|
+
|
21
|
+
|
22
|
+
# EXAMPLE 2:
|
23
|
+
# Search through the contacts of the
|
24
|
+
# account associated with the provided
|
25
|
+
# OAuth token
|
26
|
+
contacts = DwollaUser.contacts(:search => 'Ben')
|
27
|
+
pp contacts
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Include the Dwolla gem
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pp'
|
4
|
+
require 'dwolla'
|
5
|
+
|
6
|
+
# Include any required keys
|
7
|
+
require '_keys.rb'
|
8
|
+
|
9
|
+
# Instantiate a new Dwolla User client
|
10
|
+
# And, Sseed a previously generated access token
|
11
|
+
DwollaUser = Dwolla::User.me($token)
|
12
|
+
|
13
|
+
|
14
|
+
# EXAMPLE 1:
|
15
|
+
# Fetch all funding sources for the
|
16
|
+
# account associated with the provided
|
17
|
+
# OAuth token
|
18
|
+
sources = DwollaUser.funding_sources()
|
19
|
+
pp sources
|
20
|
+
|
21
|
+
|
22
|
+
# EXAMPLE 2:
|
23
|
+
# Fetch detailed information for the
|
24
|
+
# funding source with a specific ID
|
25
|
+
source = DwollaUser.funding_source('pJRq4tK38fiAeQ8xo2iH9Q==')
|
26
|
+
pp source
|
data/examples/oauth.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Include the Dwolla gem
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pp'
|
4
|
+
require 'sinatra'
|
5
|
+
require '../lib/dwolla'
|
6
|
+
|
7
|
+
# Include any required keys
|
8
|
+
require './_keys.rb'
|
9
|
+
|
10
|
+
# Instantiate a new Dwolla User client
|
11
|
+
# And, Sseed a previously generated access token
|
12
|
+
DwollaClient = Dwolla::Client.new($apiKey, $apiSecret)
|
13
|
+
|
14
|
+
# Constants...
|
15
|
+
redirect_uri = 'http://localhost:4567/oauth_return'
|
16
|
+
|
17
|
+
|
18
|
+
# STEP 1:
|
19
|
+
# Create an authentication URL
|
20
|
+
# that the user will be redirected to
|
21
|
+
get '/' do
|
22
|
+
authUrl = DwollaClient.auth_url(redirect_uri)
|
23
|
+
"To begin the OAuth process, send the user off to <a href=\"#{authUrl}\">#{authUrl}</a>"
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
# STEP 2:
|
28
|
+
# Exchange the temporary code given
|
29
|
+
# to us in the querystring, for
|
30
|
+
# a never-expiring OAuth access token
|
31
|
+
get '/oauth_return' do
|
32
|
+
code = params['code']
|
33
|
+
token = DwollaClient.request_token(code, redirect_uri)
|
34
|
+
"Your never-expiring OAuth access token is: <b>#{token}</b>"
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Coming soon...
|
data/examples/send.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Include the Dwolla gem
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pp'
|
4
|
+
require '../lib/dwolla'
|
5
|
+
|
6
|
+
# Include any required keys
|
7
|
+
require '_keys.rb'
|
8
|
+
|
9
|
+
# Instantiate a new Dwolla User client
|
10
|
+
# And, Sseed a previously generated access token
|
11
|
+
DwollaUser = Dwolla::User.me($token)
|
12
|
+
|
13
|
+
|
14
|
+
# EXAMPLE 1:
|
15
|
+
# Send money ($1.00) to a Dwolla ID
|
16
|
+
transactionId = DwollaUser.send_money_to('812-626-8794', 1.00, $pin)
|
17
|
+
pp transactionId
|
18
|
+
|
19
|
+
|
20
|
+
# EXAMPLE 2:
|
21
|
+
# Send money ($1.00) to an email address, with a note
|
22
|
+
transactionId = DwollaUser.send_money_to('michael@dwolla.com', 1.00, $pin, 'Email', 'Everyone loves getting money')
|
23
|
+
pp transactionId
|
data/lib/dwolla.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Dwolla
|
2
|
+
def self.endpoint=(endpoint)
|
3
|
+
@@endpoint = endpoint
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.endpoint
|
7
|
+
@@endpoint
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.user_agent=(user_agent)
|
11
|
+
@@user_agent = user_agent
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.user_agent
|
15
|
+
@@user_agent
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.debugging?
|
19
|
+
!!@@debug
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.debug=(debug)
|
23
|
+
@@debug = debug
|
24
|
+
end
|
25
|
+
|
26
|
+
self.debug = false
|
27
|
+
self.user_agent = "Dwolla Ruby Wrapper"
|
28
|
+
self.endpoint = "https://www.dwolla.com/oauth/rest"
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'faraday'
|
32
|
+
require 'multi_json'
|
33
|
+
|
34
|
+
require "#{File.dirname(__FILE__)}/dwolla/exceptions"
|
35
|
+
require "#{File.dirname(__FILE__)}/dwolla/response/parse_json"
|
36
|
+
require "#{File.dirname(__FILE__)}/dwolla/response/follow_redirects"
|
37
|
+
require "#{File.dirname(__FILE__)}/dwolla/response/guard_server_error"
|
38
|
+
require "#{File.dirname(__FILE__)}/dwolla/connection"
|
39
|
+
require "#{File.dirname(__FILE__)}/dwolla/client"
|
40
|
+
require "#{File.dirname(__FILE__)}/dwolla/transaction"
|
41
|
+
require "#{File.dirname(__FILE__)}/dwolla/funding_source"
|
42
|
+
require "#{File.dirname(__FILE__)}/dwolla/user"
|
43
|
+
require "#{File.dirname(__FILE__)}/dwolla/version"
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Dwolla
|
2
|
+
class Client
|
3
|
+
include Dwolla::Connection
|
4
|
+
|
5
|
+
def initialize(client, secret)
|
6
|
+
@client, @secret = client, secret
|
7
|
+
end
|
8
|
+
|
9
|
+
def user(id)
|
10
|
+
user_attributes_hash = get("users/#{id}")
|
11
|
+
User.new(user_attributes_hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
def auth_url(redirect_uri=nil, scope='send|transactions|balance|request|contacts|accountinfofull|funding')
|
15
|
+
params = {
|
16
|
+
'scope' => scope,
|
17
|
+
'response_type' => 'code',
|
18
|
+
'client_id' => @client
|
19
|
+
}
|
20
|
+
unless redirect_uri.nil?
|
21
|
+
params['redirect_uri'] = redirect_uri
|
22
|
+
end
|
23
|
+
querystring = params.map{|k,v| "#{CGI.escape(k)}=#{CGI.escape(v)}"}.join("&")
|
24
|
+
|
25
|
+
return 'https://www.dwolla.com/oauth/v2/authenticate?' + querystring
|
26
|
+
end
|
27
|
+
|
28
|
+
def request_token(code, redirect_uri=nil)
|
29
|
+
params = {
|
30
|
+
'client_id' => @client,
|
31
|
+
'client_secret' => @secret,
|
32
|
+
'grant_type' => 'authorization_code',
|
33
|
+
'code' => code
|
34
|
+
}
|
35
|
+
unless redirect_uri.nil?
|
36
|
+
params['redirect_uri'] = redirect_uri
|
37
|
+
end
|
38
|
+
|
39
|
+
resp = get('https://www.dwolla.com/oauth/v2/token', params)
|
40
|
+
|
41
|
+
return resp['access_token']
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def auth_params
|
47
|
+
{ :client_id => @client, :client_secret => @secret }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Dwolla
|
2
|
+
module Connection
|
3
|
+
private
|
4
|
+
def connection
|
5
|
+
default_options = {
|
6
|
+
:headers => {
|
7
|
+
:accept => 'application/json',
|
8
|
+
:content_type => 'application/json',
|
9
|
+
:user_agent => Dwolla.user_agent,
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
@connection ||= Faraday.new(Dwolla.endpoint, default_options) do |builder|
|
14
|
+
builder.use Dwolla::Response::FollowRedirects
|
15
|
+
builder.use Dwolla::Response::ParseJson
|
16
|
+
builder.use Dwolla::Response::GuardServerError
|
17
|
+
|
18
|
+
builder.use Faraday::Request::UrlEncoded
|
19
|
+
|
20
|
+
builder.response :logger if Dwolla.debugging?
|
21
|
+
builder.adapter Faraday.default_adapter
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(path, params={})
|
26
|
+
request(:get, path, params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def post(path, params={})
|
30
|
+
request(:post, path, params)
|
31
|
+
end
|
32
|
+
|
33
|
+
def request(method, path, params)
|
34
|
+
response = connection.send(method) do |request|
|
35
|
+
case method.to_sym
|
36
|
+
when :delete, :get
|
37
|
+
request.url(path, params.merge(auth_params))
|
38
|
+
when :post
|
39
|
+
request.path = path
|
40
|
+
params.merge!(auth_params) if auth_params
|
41
|
+
request.body = MultiJson.dump(params) unless params.empty?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
response.body
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|