Skip to content

Instantly share code, notes, and snippets.

@danchoi
Created March 18, 2013 20:28
Show Gist options
  • Select an option

  • Save danchoi/5190510 to your computer and use it in GitHub Desktop.

Select an option

Save danchoi/5190510 to your computer and use it in GitHub Desktop.
balanced.rb
require 'httparty'
module Balanced
module_function
class HTTPError < StandardError
attr_reader :response
attr_reader :message
def initialize(response, message)
@response = response
@message = message
end
def to_s
"#{response.code}: #{message}"
end
end
class ServerError < HTTPError; end
class ClientError < HTTPError; end
MATTRS = %w(api_key marketplace)
mattr_accessor *(MATTRS.map(&:to_sym))
def setup
yield self
end
def base_uri
@@base_uri ||= 'https://api.balancedpayments.com'
end
def basic_auth
@@basic_auth ||= { username: api_key}
end
def default_headers
@@default_headers ||= { 'content-type' => 'application/json' }
end
def default_options
@@default_options ||= {
:base_uri => base_uri,
:basic_auth => basic_auth,
:headers => default_headers
}
end
[:get, :post, :put, :delete].each do |verb|
define_method(verb) do |path, options={}|
HTTParty.send(verb, path, default_options.merge(options)).tap do |response|
if response.server_error?
raise ServerError.new(response, response.parsed_response['description'])
elsif response.client_error?
raise ClientError.new(response, response.parsed_response['description'])
end
end
end
module_function verb
end
#just for testing to generate fake api key and marketplace
def generate_api_key_and_marketplace
api_key = HTTParty.post('https://api.balancedpayments.com/v1/api_keys').parsed_response
basic_auth = { username: api_key["secret"] }
marketplace = HTTParty.post('https://api.balancedpayments.com/v1/marketplaces', basic_auth: basic_auth).parsed_response
[api_key, marketplace]
end
def tokenize_card(data)
post marketplace["cards_uri"], :body => data.to_json
end
def tokenize_merchant_account(data)
post marketplace["bank_accounts_uri"], :body => data.to_json
end
def create_account(data)
post marketplace["accounts_uri"], :body => data.to_json
end
def find_or_create_account(email)
create_account(:email_address => email)
rescue ClientError
raise unless $!.response.conflict?
get(marketplace['accounts_uri'], :query => { 'email_address' => email })['items'].first
end
def find_or_create_merchant_account(data)
data = data.with_indifferent_access
create_account(data)
rescue ClientError, ServerError
raise unless $!.response.conflict?
account = self.query_account(email_address: data['email_address'])['items'].first
begin
#response = self.put(account['uri'], body: {bank_account_uri: data['bank_account_uri']}.to_json)
uri = URI.parse(@@base_uri)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Put.new(account['uri'])
request.basic_auth(api_key, "")
request.set_form_data({"bank_account_uri" => data['bank_account_uri']})
response = http.request(request)
ActiveSupport::JSON.decode(response.body)
rescue
puts "Couldn't add bank account: #{response}"
end
end
def add_card_to_account(account, card_uri)
put account['uri'], :body => {card_uri: card_uri}.to_json
true
rescue ClientError
raise unless $!.response.conflict?
# but don't complain if the card is already associated with the account
true
end
def add_bank_to_account(account, bank_account_uri)
post account['bank_accounts_uri'], :body => data.to_json
true
rescue ClientError
raise unless $!.response.conflict?
# but don't complain if the bank is already associated with the account
true
end
def query_account(query)
get marketplace["accounts_uri"], :query => query
end
def create_authorization(buyer, amount)
post buyer["holds_uri"], :body => { amount: amount }.to_json
end
def all_transactions(buyer)
get buyer["transactions_uri"]
end
def transaction_exists_for_buyer_and_donation?(buyer, donation_uid)
donation_id = donation_uid.to_s
transactions = get(buyer["transactions_uri"]).parsed_response
transactions['items'].any? do |item|
next unless item.key? 'debit'
next unless item['debit']['meta'].key? 'donation_id'
item['debit']['meta']['donation_id'] == donation_uid
end
end
def debit_authorization(authorization, donation_id=nil)
post authorization["uri"] + '/debits', :body => {:meta => {:donation_id => donation_id}}.to_json
end
def create_debit_for_donation(buyer, donation)
post(buyer['debits_uri'], :body => {
source_uri: donation.card_uri,
amount: donation.amount_cents,
meta: {donation_id: donation.uid},
description: "Cause: #{donation.cause.name}"
}.to_json
)
end
def pay_out_for_credit(credit)
merchant = get credit.merchant.uri
if already_credited?(merchant, credit.uid)
nil
else
post merchant['credits_uri'], :body => {
amount: credit.amount_credited_cents,
appears_on_statement_as: 'SharingCounts',
meta: {credit_id: credit.uid} }.to_json
end
end
def already_credited?(merchant, credit_id)
transactions = get(merchant["credits_uri"]).parsed_response
#puts "transactions for merchant #{merchant['name']}:"
#pp transactions['items']
transactions['items'].any? do |item|
next unless item.key? 'account'
next unless item['account']['meta'].key? 'credit_id'
item['account']['meta']['credit_id'] == credit_id
end
end
def accounts
get marketplace["accounts_uri"]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment