Module: Paysimple

Defined in:
lib/paysimple.rb,
lib/paysimple/util.rb,
lib/paysimple/config.rb,
lib/paysimple/version.rb,
lib/paysimple/endpoint.rb,
lib/paysimple/resources/ach.rb,
lib/paysimple/errors/api_error.rb,
lib/paysimple/resources/payment.rb,
lib/paysimple/resources/customer.rb,
lib/paysimple/enumerations/issuer.rb,
lib/paysimple/resources/credit_card.rb,
lib/paysimple/errors/paysimple_error.rb,
lib/paysimple/resources/payment_plan.rb,
lib/paysimple/enumerations/payment_type.rb,
lib/paysimple/enumerations/payment_status.rb,
lib/paysimple/errors/api_connection_error.rb,
lib/paysimple/errors/authentication_error.rb,
lib/paysimple/resources/recurring_payment.rb,
lib/paysimple/enumerations/schedule_status.rb,
lib/paysimple/errors/invalid_request_error.rb,
lib/paysimple/enumerations/payment_sub_type.rb,
lib/paysimple/enumerations/execution_frequency_type.rb

Defined Under Namespace

Modules: Util Classes: ACH, APIConnectionError, APIError, AuthenticationError, Config, CreditCard, Customer, Endpoint, ExecutionFrequencyType, InvalidRequestError, Issuer, Payment, PaymentPlan, PaymentStatus, PaymentSubType, PaymentType, PaysimpleError, RecurringPayment, ScheduleStatus

Constant Summary collapse

VERSION =
'0.2.1'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.api_endpointObject

Returns the value of attribute api_endpoint.



43
44
45
# File 'lib/paysimple.rb', line 43

def api_endpoint
  @api_endpoint
end

.api_keyObject

Returns the value of attribute api_key.



43
44
45
# File 'lib/paysimple.rb', line 43

def api_key
  @api_key
end

.api_userObject

Returns the value of attribute api_user.



43
44
45
# File 'lib/paysimple.rb', line 43

def api_user
  @api_user
end

.ssl_versionObject

Returns the value of attribute ssl_version.



43
44
45
# File 'lib/paysimple.rb', line 43

def ssl_version
  @ssl_version
end

Class Method Details

.api_url(url = '') ⇒ Object



82
83
84
# File 'lib/paysimple.rb', line 82

def self.api_url(url='')
  @api_endpoint + '/v4' + url
end

.authorization_headerObject



118
119
120
121
122
123
124
125
# File 'lib/paysimple.rb', line 118

def self.authorization_header
  utc_timestamp = Time.now.getutc.iso8601.encode(Encoding::UTF_8)
  secret_key = @api_key.encode(Encoding::UTF_8)
  hash = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), secret_key, utc_timestamp)
  signature = Base64.encode64(hash)

  "PSSERVER accessid=#{@api_user}; timestamp=#{utc_timestamp}; signature=#{signature}"
end

.execute_request(opts) ⇒ Object



86
87
88
# File 'lib/paysimple.rb', line 86

def self.execute_request(opts)
  RestClient::Request.execute(opts)
end

.general_api_error(rcode, rbody) ⇒ Object



113
114
115
116
# File 'lib/paysimple.rb', line 113

def self.general_api_error(rcode, rbody)
  APIError.new("Invalid response object from API: #{rbody.inspect} " +
                   "(HTTP response code was #{rcode})", rcode, rbody)
end

.handle_api_error(rcode, rbody) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/paysimple.rb', line 127

def self.handle_api_error(rcode, rbody)
  begin
    error_obj = rbody.empty? ? {} : Util.underscore_and_symbolize_names(JSON.parse(rbody))
  rescue JSON::ParserError
    raise general_api_error(rcode, rbody)
  end

  case rcode
    when 400, 404
      errors = error_obj[:meta][:errors][:error_messages].collect { |e| e[:message]}
      raise InvalidRequestError.new(errors, rcode, rbody, error_obj)
    when 401
      error = "Error getting an API token. Check your authentication credentials and resubmit."
      raise AuthenticationError.new(error, rcode, rbody, error_obj)
    else
      error = "There was an error processing the request."
      raise APIError.new(error, rcode, rbody, error_obj)
  end
end

.handle_restclient_error(e, api_base_url = nil) ⇒ Object

Raises:



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/paysimple.rb', line 147

def self.handle_restclient_error(e, api_base_url=nil)
  connection_message = 'Please check your internet connection and try again.'

  case e
    when RestClient::RequestTimeout
      message = "Could not connect to Paysimple (#{@api_endpoint}). #{connection_message}"
    when RestClient::ServerBrokeConnection
      message = "The connection to the server (#{@api_endpoint}) broke before the " \
      "request completed. #{connection_message}"
    when SocketError
      message = 'Unexpected error communicating when trying to connect to Paysimple. ' \
      'You may be seeing this message because your DNS is not working. '
    else
      message = 'Unexpected error communicating with Paysimple. '
  end

  raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
end

.parse(response) ⇒ Object



102
103
104
105
106
107
108
109
110
111
# File 'lib/paysimple.rb', line 102

def self.parse(response)
  if response.body.empty?
    {}
  else
    response = JSON.parse(response.body)
    Util.underscore_and_symbolize_names(response)[:response]
  end
rescue JSON::ParserError
  raise general_api_error(response.code, response.body)
end

.request(method, url, params = {}) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/paysimple.rb', line 46

def self.request(method, url, params={})

  raise AuthenticationError.new('API key is not provided.') unless @api_key
  raise AuthenticationError.new('API user is not provided.') unless @api_user

  url = api_url(url)
  case method
    when :get, :head
      url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
      payload = nil
    when :delete
      payload = nil
    else
      payload = Util.camelize_and_symbolize_keys(params).to_json
  end

  request_opts = { headers: request_headers, method: method, open_timeout: 30,
                   payload: payload, url: url, timeout: 80, ssl_version: ssl_version }

  begin
    response = execute_request(request_opts)
  rescue SocketError => e
    handle_restclient_error(e)
  rescue RestClient::ExceptionWithResponse => e
    if rcode = e.http_code and rbody = e.http_body
      handle_api_error(rcode, rbody)
    else
      handle_restclient_error(e)
    end
  rescue RestClient::Exception, Errno::ECONNREFUSED => e
    handle_restclient_error(e)
  end

  parse(response)
end

.request_headersObject



90
91
92
93
94
95
96
# File 'lib/paysimple.rb', line 90

def self.request_headers
  {
      authorization: authorization_header,
      content_type: :json,
      accept: :json
  }
end

.uri_encode(params) ⇒ Object



98
99
100
# File 'lib/paysimple.rb', line 98

def self.uri_encode(params)
  Util.flatten_params(params).map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
end