Skip to content

Instantly share code, notes, and snippets.

@kyledrake
Last active August 29, 2015 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kyledrake/214221ab4bd10b78a585 to your computer and use it in GitHub Desktop.
Save kyledrake/214221ab4bd10b78a585 to your computer and use it in GitHub Desktop.
A not-crazy Paypal REST API interface.
# Everything else was worse...
# https://developer.paypal.com/docs/api/
require 'rest_client'
require 'addressable/uri'
require 'thread'
class Paypal
OAUTH2_IS_INCREDIBLY_SHITTY_COMEDY_TIME_PADDING = 10
SANDBOX_URI = Addressable::URI.parse 'https://api.sandbox.paypal.com/v1'
LIVE_URI = Addressable::URI.parse 'https://api.paypal.com/v1'
def initialize(client_id, client_secret, mode='live')
@client_id = client_id
@client_secret = client_secret
@uri = (mode == 'live' ? LIVE_URI : SANDBOX_URI)
@semaphore = Mutex.new
end
def uri_for(path)
uri = @uri.clone
uri.path = uri.path + path
uri
end
def refresh_token
uri = uri_for '/oauth2/token'
uri.user = @client_id
uri.password = @client_secret
res = execute :post, uri, grant_type: 'client_credentials'
@semaphore.synchronize {
@access_token = res[:access_token]
@access_token_expiration = Time.now + res[:expires_in] - OAUTH2_IS_INCREDIBLY_SHITTY_COMEDY_TIME_PADDING
}
end
def access_token_expired?
return true if @access_token_expiration.nil? || Time.now > @access_token_expiration
false
end
def execute(meth, uri, args={}, headers={}, &block)
request_args = {
method: meth,
headers: headers.merge(accept: 'application/json', accept_language: 'en_US')
}
if meth == :get
uri.query_values = args
elsif meth == :post
request_args[:payload] = args
end
request_args[:url] = uri.to_s
JSON.parse RestClient::Request.execute(request_args, &block), symbolize_names: true
end
def execute_with_token(meth, uri, args=nil, headers={}, &block)
refresh_token if access_token_expired?
headers.merge! authorization: "Bearer #{@access_token}"
execute meth, uri, args, headers, &block
end
def get(path, args=nil, headers={}, &block)
execute_with_token :get, uri_for(path), headers, &block
end
def post(path, args, headers)
execute_with_token :post, uri_for(path), args, headers, &block
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment