class Invoiced::Client

Constants

ApiBase
ApiBaseSandbox
OpenTimeout
ReadTimeout

Attributes

Charge[R]
Coupon[R]
CreditBalanceAdjustment[R]
CreditNote[R]
Customer[R]
Estimate[R]
Event[R]
File[R]
Invoice[R]
Item[R]
Note[R]
Payment[R]
Plan[R]
Refund[R]
Subscription[R]
Task[R]
TaxRate[R]
api_key[R]
api_url[R]
sandbox[R]
sso_key[R]

Public Class Methods

new(api_key, sandbox=false, sso_key=false) click to toggle source
# File lib/invoiced.rb, line 61
def initialize(api_key, sandbox=false, sso_key=false)
  @api_key = api_key
  @sandbox = sandbox
  @api_url = sandbox ? ApiBaseSandbox : ApiBase
  @sso_key = sso_key

  # Object endpoints
  @Item = Invoiced::Item.new(self)
  @Charge = Invoiced::Charge.new(self)
  @Coupon = Invoiced::Coupon.new(self)
  @CreditBalanceAdjustment = Invoiced::CreditBalanceAdjustment.new(self)
  @CreditNote = Invoiced::CreditNote.new(self)
  @Customer = Invoiced::Customer.new(self)
  @Estimate = Invoiced::Estimate.new(self)
  @Event = Invoiced::Event.new(self)
  @File = Invoiced::File.new(self)
  @Invoice = Invoiced::Invoice.new(self)
  @Note = Invoiced::Note.new(self)
  @Payment = Invoiced::Payment.new(self)
  @Plan = Invoiced::Plan.new(self)
  @Refund = Invoiced::Refund.new(self)
  @Subscription = Invoiced::Subscription.new(self)
  @Task = Invoiced::Task.new(self)
  @TaxRate = Invoiced::TaxRate.new(self)
end

Public Instance Methods

generate_sign_in_token(customerId, ttl) click to toggle source
# File lib/invoiced.rb, line 121
def generate_sign_in_token(customerId, ttl)
    if !@sso_key
        raise "Please provide a single sign-on key! You can find this value in Settings > Developers > Single Sign-On of the Invoiced application."
    end

    expires = Time.now + ttl # TTL should be in seconds

    payload = {
        :sub => customerId,
        :iss => "Invoiced Ruby/#{Invoiced::VERSION}",
        :iat => Time.now.to_i,
        :exp => expires.to_i
    }

    JWT.encode payload, @sso_key, 'HS256'
end
request(method, endpoint, params={}, opts={}) click to toggle source
# File lib/invoiced.rb, line 87
def request(method, endpoint, params={}, opts={})
    url = @api_url + endpoint

    case method.to_s.downcase.to_sym
    # These methods don't have a request body
    when :get, :head, :delete
        # Make params into GET parameters
        url += "#{URI.parse(url).query ? '&' : '?'}#{Util.uri_encode(params)}" if params && params.any?
        payload = nil
    # Otherwise, encode request body to JSON
    else
        payload = params.to_json
    end

    begin
        response = RestClient::Request.execute(
            :method => method,
            :url => url,
            :headers => buildHeaders(opts),
            :payload => payload,
            :open_timeout => OpenTimeout,
            :timeout => ReadTimeout
        )
    rescue RestClient::Exception => e
        if e.response
            handle_api_error(e.response)
        else
            handle_network_error(e)
        end
    end

    parse(response)
end

Private Instance Methods

api_error(error, response) click to toggle source
# File lib/invoiced.rb, line 217
def api_error(error, response)
    ApiError.new(error["message"], response.code, error)
end
authentication_error(error, response) click to toggle source
# File lib/invoiced.rb, line 205
def authentication_error(error, response)
    AuthenticationError.new(error["message"], response.code, error)
end
buildHeaders(opts) click to toggle source
# File lib/invoiced.rb, line 140
def buildHeaders(opts)
    headers = {
        :authorization => Util.auth_header(@api_key),
        :content_type => "application/json",
        :user_agent => "Invoiced Ruby/#{Invoiced::VERSION}"
    }

    # idempotency keys
    if opts[:idempotency_key]
        headers[:idempotency_key] = opts[:idempotency_key]
    end

    return headers
end
general_api_error(code, body) click to toggle source
# File lib/invoiced.rb, line 221
def general_api_error(code, body)
    ApiError.new("API Error #{code} - #{body}", code)
end
handle_api_error(response) click to toggle source
# File lib/invoiced.rb, line 169
def handle_api_error(response)
    begin
        error = JSON.parse(response.body)
    rescue JSON::ParserError
        raise general_api_error(response.code, response.body)
    end

    case response.code
    when 400, 403, 404
        raise invalid_request_error(error, response)
    when 401
        raise authentication_error(error, response)
    when 429
        raise rate_limit_error(error, response)
    else
        raise api_error(error, response)
    end
end
handle_network_error(error) click to toggle source
# File lib/invoiced.rb, line 188
def handle_network_error(error)
    case error
    when RestClient::Exceptions::OpenTimeout
        message = "Timed out while connecting to Invoiced. Please check your internet connection or status.invoiced.com for service outages."
    when RestClient::Exceptions::ReadTimeout
        message = "The request timed out reading data from the server."
    when RestClient::ServerBrokeConnection
        message = "Connection with the server was broken while receiving the response."
    when RestClient::SSLCertificateNotVerified
        message = "Failed to verify the Invoiced SSL certificate. Please verify that you have a recent version of OpenSSL installed."
    else
        message = "There was an error connecting to Invoiced: #{error.message}"
    end

    raise ApiConnectionError.new(message)
end
invalid_request_error(error, response) click to toggle source
# File lib/invoiced.rb, line 209
def invalid_request_error(error, response)
    InvalidRequestError.new(error["message"], response.code, error)
end
parse(response) click to toggle source
# File lib/invoiced.rb, line 155
def parse(response)
    unless response.code == 204
        parsed_response = JSON.parse(response.body, :symbolize_names => true)
    else
        parsed_response = nil
    end

    {
        :code => response.code,
        :headers => response.headers,
        :body => parsed_response
    }
end
rate_limit_error(error, response) click to toggle source
# File lib/invoiced.rb, line 213
def rate_limit_error(error, response)
    RateLimitError.new(error["message"], response.code, error)
end