module Dwolla

Constants

VERSION

Public Class Methods

api_key() click to toggle source
# File lib/dwolla.rb, line 48
def self.api_key
    @@api_key
end
api_key=(api_key) click to toggle source
# File lib/dwolla.rb, line 44
def self.api_key=(api_key)
    @@api_key = api_key
end
api_secret() click to toggle source
# File lib/dwolla.rb, line 56
def self.api_secret
    @@api_secret
end
api_secret=(api_secret) click to toggle source
# File lib/dwolla.rb, line 52
def self.api_secret=(api_secret)
    @@api_secret = api_secret
end
api_version() click to toggle source
# File lib/dwolla.rb, line 80
def self.api_version
    @@api_version
end
api_version=(api_version) click to toggle source
# File lib/dwolla.rb, line 76
def self.api_version=(api_version)
    @@api_version = api_version
end
debug() click to toggle source
# File lib/dwolla.rb, line 68
def self.debug
    @@debug
end
debug=(debug) click to toggle source
# File lib/dwolla.rb, line 72
def self.debug=(debug)
    @@debug = debug
end
endpoint_url(endpoint) click to toggle source
# File lib/dwolla.rb, line 116
def self.endpoint_url(endpoint)
    self.hostname + @@api_base + endpoint
end
hostname() click to toggle source
# File lib/dwolla.rb, line 108
def self.hostname
    if not @@sandbox
        return 'https://www.dwolla.com'
    else
        return 'https://sandbox.dwolla.com'
    end
end
request(method, url, params={}, headers={}, oauth=true, parse_response=true, custom_url=false) click to toggle source
# File lib/dwolla.rb, line 120
def self.request(method, url, params={}, headers={}, oauth=true, parse_response=true, custom_url=false)
    self.extract_authorization(params, headers, oauth)
    
    if !verify_ssl_certs
        $stderr.puts "WARNING: Running without SSL cert verification."
    else
        ssl_opts = {
            :use_ssl => true
        }
    end

    uname = (@@uname ||= RUBY_PLATFORM =~ /linux|darwin/i ? `uname -a 2>/dev/null`.strip : nil)
    lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
    ua = {
        :bindings_version => Dwolla::VERSION,
        :lang => 'ruby',
        :lang_version => lang_version,
        :platform => RUBY_PLATFORM,
        :publisher => 'dwolla',
        :uname => uname
    }

    url = self.endpoint_url(url) unless custom_url

    case method.to_s.downcase.to_sym
        when :get || :delete
            # Make params into GET/DELETE parameters
            if params && params.count > 0
                uri = Addressable::URI.new
                uri.query_values = params
                url += '?' + uri.query
            end
            payload = nil
        else
            payload = JSON.dump(params)
    end

    begin
        headers = { :x_dwolla_client_user_agent => Dwolla::JSON.dump(ua) }.merge(headers)
    rescue => e
        headers = {
            :x_dwolla_client_raw_user_agent => ua.inspect,
            :error => "#{e} (#{e.class})"
        }.merge(headers)
    end

    headers = {
        :user_agent => "Dwolla Ruby API Wrapper/#{Dwolla::VERSION}",
        :content_type => 'application/json'
    }.merge(headers)

    if self.api_version
        headers[:dwolla_version] = self.api_version
    end

    opts = {
        :method => method,
        :url => url,
        :headers => headers,
        :open_timeout => 30,
        :payload => payload,
        :timeout => 80
    }.merge(ssl_opts)

    if self.debug
        if self.sandbox
            puts "[DWOLLA SANDBOX MODE OPERATION]"
        end

        puts "Firing request with options and headers:"
        puts opts
        puts headers
    end

    begin
        response = execute_request(opts)
    rescue SocketError => e
        self.handle_restclient_error(e)
    rescue NoMethodError => e
        # Work around RestClient bug
        if e.message =~ /\WRequestFailed\W/
            e = APIConnectionError.new('Unexpected HTTP response code')
            self.handle_restclient_error(e)
        else
            raise
        end
    rescue RestClient::ExceptionWithResponse => e
        if rcode = e.http_code and rbody = e.http_body
            self.handle_api_error(rcode, rbody)
        else
            self.handle_restclient_error(e)
        end
    rescue RestClient::Exception, Errno::ECONNREFUSED => e
        self.handle_restclient_error(e)
    end

    rbody = response.body
    rcode = response.code

    if self.debug
        puts "Raw response headers received:"
        puts headers
        puts "Raw response body received:"
        puts rbody
    end

    resp = self.extract_json(rbody, rcode)

    if parse_response
        return self.parse_response(resp)
    else
        return resp
    end
end
sandbox() click to toggle source
# File lib/dwolla.rb, line 64
def self.sandbox
    @@sandbox
end
sandbox=(sandbox) click to toggle source
# File lib/dwolla.rb, line 60
def self.sandbox=(sandbox)
    @@sandbox = sandbox
end
scope() click to toggle source
# File lib/dwolla.rb, line 104
def self.scope
    @@scope
end
scope=(scope) click to toggle source
# File lib/dwolla.rb, line 100
def self.scope=(scope)
    @@scope = scope
end
token() click to toggle source
# File lib/dwolla.rb, line 96
def self.token
    @@token
end
token=(token) click to toggle source
# File lib/dwolla.rb, line 92
def self.token=(token)
    @@token = token
end
verify_ssl_certs() click to toggle source
# File lib/dwolla.rb, line 88
def self.verify_ssl_certs
    @@verify_ssl_certs
end
verify_ssl_certs=(verify_ssl_certs) click to toggle source
# File lib/dwolla.rb, line 84
def self.verify_ssl_certs=(verify_ssl_certs)
    @@verify_ssl_certs = verify_ssl_certs
end

Private Class Methods

api_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/dwolla.rb, line 284
def self.api_error(error, rcode, rbody, error_obj)
    APIError.new(error[:message], rcode, rbody, error_obj)
end
authentication_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/dwolla.rb, line 280
def self.authentication_error(error, rcode, rbody, error_obj)
    AuthenticationError.new(error[:message], rcode, rbody, error_obj)
end
execute_request(opts) click to toggle source
# File lib/dwolla.rb, line 237
def self.execute_request(opts)
    RestClient::Request.execute(opts)
end
extract_authorization(params={}, headers={}, oauthToken=true) click to toggle source
# File lib/dwolla.rb, line 288
def self.extract_authorization(params={}, headers={}, oauthToken=true)
    paramsToken = params.delete(:oauth_token)
    if oauthToken.is_a?(FalseClass) 
        raise AuthenticationError.new('No App Key & Secret Provided.') unless (api_key && api_secret)
        params[:client_id] = api_key
        params[:client_secret] = api_secret
    else
        providedAuthorization = oauthToken.is_a?(TrueClass) ? token : oauthToken
        t = paramsToken || providedAuthorization
        raise AuthenticationError.new('No OAuth Token Provided.') unless t
        headers[:authorization] = "Bearer #{t}"
    end

end
extract_json(rbody, rcode) click to toggle source
# File lib/dwolla.rb, line 241
def self.extract_json(rbody, rcode)
    begin
        resp = Dwolla::JSON.load(rbody)
    rescue MultiJson::DecodeError
        raise APIError.new("There was an error parsing Dwolla's API response: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
    end

    return resp
end
handle_api_error(rcode, rbody) click to toggle source
# File lib/dwolla.rb, line 258
def self.handle_api_error(rcode, rbody)
    begin
        error_obj = Dwolla::JSON.load(rbody)
        error = error_obj[:error] or raise DwollaError.new # escape from parsing
    rescue MultiJson::DecodeError, DwollaError
        raise APIError.new("Invalid response object from API: #{rbody.inspect} (HTTP response code was #{rcode})", rcode, rbody)
    end

    case rcode
        when 400, 404 then
            raise invalid_request_error(error, rcode, rbody, error_obj)
        when 401
            raise authentication_error(error, rcode, rbody, error_obj)
        else
            raise api_error(error, rcode, rbody, error_obj)
    end
end
handle_restclient_error(e) click to toggle source
# File lib/dwolla.rb, line 303
def self.handle_restclient_error(e)
    case e
        when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
            message = "Could not connect to Dwolla (#{@@api_base}).  Please check your internet connection and try again.  If this problem persists, you should check Dwolla's service status at https://twitter.com/Dwolla, or let us know at support@Dwolla.com."
        when RestClient::SSLCertificateNotVerified
            message = "Could not verify Dwolla's SSL certificate. If this problem persists, let us know at support@dwolla.com."
        when SocketError
            message = "Unexpected error communicating when trying to connect to Dwolla. If this problem persists, let us know at support@dwolla.com."
        else
            message = "Unexpected error communicating with Dwolla. If this problem persists, let us know at support@dwolla.com."
    end

    message += "\n\n(Network error: #{e.message})"

    raise APIConnectionError.new(message)
end
invalid_request_error(error, rcode, rbody, error_obj) click to toggle source
# File lib/dwolla.rb, line 276
def self.invalid_request_error(error, rcode, rbody, error_obj)
    InvalidRequestError.new(error[:message], error[:param], rcode, rbody, error_obj)
end
parse_response(resp) click to toggle source
# File lib/dwolla.rb, line 251
def self.parse_response(resp)
    raise APIConnectionError.new("Network issue / unserializable response. Please try again.") unless resp.is_a?(Hash)
    raise APIError.new(resp['Message']) unless resp.has_key?('Success') and resp['Success'] == true

    return resp['Response']
end