balanced / balanced-ruby Goto Github PK
View Code? Open in Web Editor NEWBalanced API library in ruby.
License: MIT License
Balanced API library in ruby.
License: MIT License
Balanced::Account#debit accepts "on_behalf_of" as a option, but Balanced::Card#debit does not. It can be added simply by ignoring positionals (or make it arg[4]) and grabbing from options:
on_behalf_of = options.fetch(:on_behalf_of) { nil }
And then pass it in on the self.account.debit call below.
As an aside, it would also be useful to clean up the parameters to "debit" as well as the documentation. In the docs, we have "account_uri", "on_behalf_of_uri", "hold_uri", "source_uri", etc. In the code, "on_behalf_of_uri" doesn't exist - it's just "on_behalf_of".
A good change would be to allow either form in Balanced::Account and Balanced::Card, e.g. "on_behalf_of" and "on_behalf_of_uri" and then properly use whichever is passed in, pulling the uri if it's the non-uri style. The code in Balanced::Account already does that, but it's a bit clunky and undocumented. If it has a "uri" method, then that is used. If it's a string, it's assumed to be a uri. The same could easily be done for all of the *_uri methods.
This gist shows an example of a bank account invalidating itself when save is called a second time.
The issue is the way the balanced-ruby client serializes the account that is returned to the server. Since Balanced cannot parse the account as it is returned it takes this to mean "disassociate this bank account from the account" and invalidates it during this process.
The balanced-ruby library should not set the account in the payload that goes back to Balanced.
Using gem version 0.2.5
I created a new buyer account and card, then tried to add the card to the buyer. This raised a NoMethodError.
1.9.3p125 :062 > card2 = Balanced::Card.new(
1.9.3p125 :063 > :card_number => "5105105105105100",
1.9.3p125 :064 > :expiration_month => "12",
1.9.3p125 :065 > :expiration_year => "2016",
1.9.3p125 :066 > ).save
=> #<Balanced::Card:0x00000004e24808 @attributes={"card_type"=>"mastercard", "account"=>nil, "name"=>nil, "expiration_year"=>2016, "created_at"=>"2012-05-30T17:29:30.209620Z", "brand"=>"MasterCard", "uri"=>"/v1/marketplaces/MKe83991b6a05d11e1a8fc026ba7e239a9/cards/CC6mXB05tOBSFUewEFLIAjf", "expiration_month"=>12, "is_valid"=>true, "last_four"=>5100, "id"=>"CC6mXB05tOBSFUewEFLIAjf"}>
1.9.3p125 :067 > buyer.add_card(card2)
NoMethodError: undefined method `card_uri=' for #<Balanced::Account:0x00000004a1db38>
from .../gems/balanced-0.2.5/lib/balanced/resources.rb:57:in `add_card'
from (irb):67
from .../gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
from .../gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
from .../gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Right now, the pager does to_a
which causes an issue when you want to filter on a sub resource of an item.
We should fix this.
Example fails tokenizing card:
require 'balanced'
# create a test marketplace
api_key = Balanced::ApiKey.new.save
Balanced.configure(api_key.secret)
marketplace = Balanced::Marketplace.new.save
# charge $100.00 on a card
buyer = Balanced::Account.new(
:email_address => "[email protected]",
:card => {
:card_number => "4111 1111 1111 1111",
:expiration_month => 12,
:expiration_year => 2014
}
).save
Error message:
Balanced::Conflict: Balanced::Conflict(409)::Conflict:: POST https://api.balancedpayments.com/v1/marketplaces/TEST-MP6v3vA90ItsYTBehUxDtchV/accounts: card-not-validated: Card cannot be validated. Your request id is OHMd6f29340029a11e294aa026ba7c1aba6.
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/response/balanced_exception_middleware.rb:28:in `on_complete'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:9:in `block in call'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:63:in `on_complete'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response/logger.rb:20:in `call'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday_middleware-0.8.8/lib/faraday_middleware/request/encode_json.rb:23:in `call'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in `run_request'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/connection.rb:99:in `post'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/client.rb:62:in `method_missing'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced.rb:70:in `post'
from /Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/resources/resource.rb:26:in `save'
from (irb):9
from /Users/marshall/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
1.9.3p194 :017 >
I've created a branch with a failing test for filtering valid cards from an account.
This should work
buyer.cards.find(:is_valid => true)
But currently it does not
require 'balanced'
# create a test marketplace
api_key = Balanced::ApiKey.new.save
Balanced.configure(api_key.secret)
marketplace = Balanced::Marketplace.new.save
# underwrite seller as a merchant
merchant = Balanced::Account.new(
:email_address => "[email protected]",
:name => "Friedrich Nietzche",
:street_address => "801 High St Ste 200",
:country_code => "USA",
:dob => "1844-10",
:bank_account => {
:name => "Fred Nietzsche",
:account_number => "204820239384",
:bank_code => "121042882"
}
).save
ba = merchant.bank_accounts[0]
ba.is_valid = false
ba.save()
Gives the following error
Balanced::BadRequest: Balanced::BadRequest(400)::Bad Request:: PUT https://api.balancedpayments.com/v1/marketplaces/TEST-MP2oVZxsDsvtqVWwobslJjvU/accounts/AC2r79awOqKaENWmuc6DygAh/bank_accounts/BA2rFF8vMNdgpQ5tv1OsfElH: : Invalid field "account.account" - Not a mapping Your request id is OHM50ed8f7ecf9711e19cd5026ba7e239a9.
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/balanced-0.3.8/lib/balanced/response/balanced_exception_middleware.rb:28:in `on_complete'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/response.rb:9:in `block in call'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/response.rb:63:in `on_complete'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/response/logger.rb:20:in `call'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday_middleware-0.8.7/lib/faraday_middleware/request/encode_json.rb:21:in `call'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in `run_request'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/faraday-0.8.1/lib/faraday/connection.rb:99:in `put'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/balanced-0.3.8/lib/balanced/client.rb:62:in `method_missing'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/balanced-0.3.8/lib/balanced.rb:68:in `method_missing'
from /usr/local/Cellar/ruby/1.9.3-p0/lib/ruby/gems/1.9.1/gems/balanced-0.3.8/lib/balanced/resources/resource.rb:26:in `save'
from (irb):24
from /usr/local/bin/irb:12:in `<main>'
Using gem version 0.2.5
I created a new merchant and bank account, then tried to add the bank account to the merchant. This raises a NoMethodError.
1.9.3p125 :068 > bank_account = Balanced::BankAccount.new(
1.9.3p125 :069 > :account_number => "1234567890",
1.9.3p125 :070 > :bank_code => "321174851",
1.9.3p125 :071 > :name => "Jack Q Merchant",
1.9.3p125 :072 > ).save
=> #<Balanced::BankAccount:0x00000004fb0348 @attributes={"bank_name"=>"SAN MATEO CREDIT UNION", "account"=>nil, "name"=>"Jack Q Merchant", "bank_code"=>"321174851", "created_at"=>"2012-05-30T17:30:32.247510Z", "uri"=>"/v1/marketplaces/MKe83991b6a05d11e1a8fc026ba7e239a9/bank_accounts/BA1e90fxRtdgam4B8LUtAhTE", "is_valid"=>true, "last_four"=>"7890", "id"=>"BA1e90fxRtdgam4B8LUtAhTE"}>
1.9.3p125 :073 > seller.add_bank_account(bank_account)
NoMethodError: undefined method `bank_account_uri=' for #<Balanced::Account:0x00000004699f70>
from .../gems/balanced-0.2.5/lib/balanced/resources.rb:62:in `add_bank_account'
from (irb):73
from .../gems/railties-3.2.3/lib/rails/commands/console.rb:47:in `start'
from .../gems/railties-3.2.3/lib/rails/commands/console.rb:8:in `start'
from .../gems/railties-3.2.3/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Much like issue #31, it would be nice for the pager to be api-compatible with Kaminari's inasmuch as that library's view helpers require in order to render pagination controls.
By DOCS - first we create an account with no data
require 'balanced'
Balanced.configure('473154884ae511e28f34026ba7cd33d0')
marketplace = Balanced::Marketplace.my_marketplace
merchant_data = {
:phone_number => '+14089999999',
:name => 'Timmy Q. CopyPasta',
:dob => '1989-12',
:postal_code => '94110',
:type => 'person',
:street_address => '121 Skriptkid Row',
}
account = Balanced::Marketplace.my_marketplace.create_account
account.promote_to_merchant(merchant_data)
Logs on dashboard contain two request POST for creation and PUT for promotion. Anyway - promote - does not respect provided email, name and so on. Getting this resource back does not contain any provided by merchant_data hash results. Is it ok ?
CURL request does this thing in one request(POST) without a problem.
Seems related to API background not the gem, because code looks ok.
The balanced API returns a 300 response when it fails to identify a merchant.
The ruby client does not support this and should raise an exception along with an appropriate message and a URL that the marketplace can redirect the user to to collect more information.
There isn't a method Marketplace#find_buyer
to get a buyer account from the Balanced system.
Applications displaying paginated query results are typically code in terms of page number and size rather than result set offset and limit. It's easy to convert between the two paradigms though, so it would be nice if the pager supported Kaminari api-compatible page
and per
params and converted them to offset
and limit
behind the scenes.
Currently the examples show how to create credits/debits and refunds.
However there are no good examples of looking up existing objects after the fact.
e.g.
While testing the library, I added a credit card to the account using:
account.add_card(credit_card_uri)
the 2nd time I got back instance of account instead of card
An new merchant account with no bank accounts will return 4
as the number of bank accounts with the following code:
api_key = Balanced::ApiKey.new.save
puts "Our secret is: ", api_key.secret
secret = api_key.secret
puts "configure with our secret #{secret}"
Balanced.configure(secret)
marketplace = Balanced::Marketplace.new.save
card = Balanced::Card.new(
:card_number => "5105105105105100",
:expiration_month => "12",
:expiration_year => "2015",
).save
buyer = marketplace.create_buyer(
:email_address => "[email protected]",
:card_uri => card.uri
)
puts buyer.bank_accounts.count
=> 2
It appears that bank_accounts is not filtering by this account, it's returning the owner_account and the marketplace merchant account.
Gimme that old skool flavor
% irb
/Users/marshall/.rvm/gems/ruby-1.8.6-p420@global/gems/rubygems-bundler-1.0.3/lib/rubygems- bundler/regenerate_binstubs_command.rb:48: warning: parenthesize argument(s) for future version
no such file to load -- wirble
1.8.6 :001 > require 'balanced'
Faraday: you may want to install system_timer for reliable timeouts
NoMethodError: undefined method `require_relative' for #<Object:0x10d045340>
from /Users/marshall/.rvm/gems/ruby-1.8.6-p420/gems/balanced-0.3.8/lib/balanced/resources/resource.rb:1
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Users/marshall/.rvm/gems/ruby-1.8.6-p420/gems/balanced-0.3.8/lib/balanced/resources.rb:2
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Users/marshall/.rvm/gems/ruby-1.8.6-p420/gems/balanced-0.3.8/lib/balanced.rb:8
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require'
from /Users/marshall/.rvm/rubies/ruby-1.8.6-p420/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from (irb):1
1.8.6 :002 >
When creating a debit through the Account.debit method, passing a card_uri parameter as documented in the API reference, that value is not passed to the Debit object. This is a problem when multiple cards are stored for a user (for example they use one card, it's declined due to ISF, then provide a second card).
Currently in the codebase, the Balanced::Error
class is used as the base exception class for all response-related errors. However, there is an instance in resource.rb where the class is used a general purpose exception class. It passes it only a string, instead of the response object the Balanced::Error
class usually expects.
One solution is to hack the error class with some conditional logic in order to make it "work" as a general purpose exception class.
Another solution might be to use a different base class for all response-related exception classes, and making Balanced::Error
a general purpose error class.
Another option would be to eliminate the one instance of the general purpose usage of the Balanced::Error
class here: https://github.com/balanced/balanced-ruby/blob/master/lib/balanced/resources/resource.rb#L96.
Either way, both are breaking changes, and any clients relying on Balanced::Error as a general purpose response error class would break, and thus, would require a minor version bump.
An third solution would be to handle the one general purpose case with a new error class -- maybe something like Balanced::StandardError
-- and leave the existing Balanced::Error
class the way it is. This solution involves the least amount of churn and is the least risky in terms of breaking existing client code.
There's still the small risk that someone is relying on Balanced::Error
being used for this one odd case, but that seems far less likely than existing client code that is relying on the Balanced::Error
class being the base class for all exceptions in this gem.
The Balanced API only filters on a subset of the returned fields.
@hold = Balanced::Hold.find(:first, id: hold.id)
This code looks like it will return the first hold with the associated ID. However, the API doesn't allow filtering on the ID field.
Balanced should either throw an error in the balanced-ruby library or document which fields are indexable.
API docs refer to the appears_on_statement_as
argument for creating a hold, but the Account#hold
implementation seems to drop that parameter.
When I ask for a Debit I should get a Debit, if it's another type of object I should get an error
require 'balanced'
key = Balanced::ApiKey.new.save
Balanced.configure(key.secret)
marketplace = Balanced::Marketplace.new.save
# this should throw an error, instead, it returns an Account object
Balanced::Debit.find(marketplace.owner_account.uri)
I'm running the spec tests and getting a whole bunch of this
Called from: /Users/marshall/code/poundpay/balanced-ruby/spec/balanced/resources/account_spec.rb:496:in `block (4 levels) in <top (required)>'
#############################################################
# WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! #
#############################################################
Using positional arguments is **DEPRECATED**. Please use the
keyword options pattern instead. Version __0.7.0__ of the
Ruby client will not support positional arguments.
If you need help, please hop on irc.freenode.net #balanced
or contact [email protected]
In my actual app I'm going to use the JS API to tokenize the credit card, yes.
But in testing, it is convenient to be able to have pure ruby code automatically create a tokenized card URI that I can test with, using one of the fake test credit card numbers.
From the API docs, I thought I'd be able to do something like this:
card = Balanced::Card.new(:uri => ENV["BALANCED_MARKETPLACE_URI"], :card_number => "4111111111111111", :security_code => "123")
The API docs say that should return something like:
{
"account": null,
"brand": "MasterCard",
"can_debit": true,
"card_type": "mastercard",
"created_at": "2013-02-22T02:02:49.812445Z",
"expiration_month": 12,
"expiration_year": 2020,
"hash": "b7250dd4b4827a88d5e4132b67f02916bce6f8e83d4ca0d779d1351b360ff6af",
"id": "CC7tyXCnrfA6pU8DLAGu7V8k",
"is_valid": true,
"last_four": "5100",
"meta": {},
"name": null,
"uri": "/v1/marketplaces/TEST-MP6E3EVlPOsagSdcBNUXWBDQ/cards/CC7tyXCnrfA6pU8DLAGu7V8k"
}
Which would be great. Note the "uri" in there, just what I need.
But I can't figure out how to get that, it doesn't actually seem to be available. In fact, if I look at card.attributes after doing a Card.new(...).save
, it seems to have the attributes of an account or a marketplace, not a card....
{"_type"=>"marketplace", "support_email_address"=>"[email protected]", "callbacks_uri"=>"/v1/marketplaces/TEST-MP4MRQi5ASoV244fYsiIBBwK/callbacks", "events_uri"=>"/v1/events" ....
And a whole bunch more. But no card_uri, just info about the marketplace as a whole.
Are the docs wrong? Am I missing something? Is there any way to tokenize a card from ruby, and get back the card uri?
There are a lot of places in the code that invoke my_marketplace
in order to acquire what are essentially static values. For example, the Balanced::Account
does the following in it's initializer in order to get the marketplace's accounts_uri:
module Balanced
# An Account represents a user within your Marketplace. An Account can have
# two +roles+. If the Account has the +buyer+ role then you may create
# Debits using this Account. If they have the +merchant+ role then you may
# create Credits to transfer funds to this Account.
#
class Account
include Balanced::Resource
def initialize attributes = {}
Balanced::Utils.stringify_keys! attributes
unless attributes.has_key? 'uri'
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
end
super attributes
end
end
end
Most other resources in the ruby client do this same thing.
This means that every single call to initialize a new Balanced::Account
object will go over the network to get info about the marketplace, which is essentially static information. Once we have it once for the runtime, I don't think we need to fetch it again. Happy to write a patch for this if we're in agreement about the solution.
When balanced sends back a 300, it appears that the ruby client reports it as a Faraday Timeout Error.
This is in an activerecord callback:
def add_bank_account
bank_account = Balanced::BankAccount.new({
account_number: bank_account_number,
bank_code: bank_routing_number,
name: name
}).save
merchant = Balanced::Marketplace.my_marketplace.create_merchant(
email,
{
type: "person",
name: name,
phone_number: "+#{phone_number}",
street_address: street_address,
postal_code: zip_code,
dob: balanced_dob
},
bank_account.uri
)
rescue Balanced::Conflict => e
@errors[:email] << "already registered"
false
rescue Exception => e
if e.respond_to?(:body)
@errors[:bank_account] << e.body["description"]
else
@errors[:bank_account] << e.message
end
Airbrake.notify(e) # Faraday::Error::TimeoutError
end
and I've attached screenshots of the logs:
Using gem version 0.2.5
I created a new buyer account and called promote_to_merchant on it. It threw a NameError.
1.9.3p125 :052 > buyer.promote_to_merchant({
1.9.3p125 :053 > :type => "person",
1.9.3p125 :054 > :name => "Billy Jones",
1.9.3p125 :055 > :street_address => "801 High St.",
1.9.3p125 :056 > :postal_code => "94301",
1.9.3p125 :057 > :country => "USA",
1.9.3p125 :058 > :dob => "1969-01",
1.9.3p125 :059 > :phone_number => "+16505551234",
1.9.3p125 :060 > })
NameError: undefined local variable or method merchant' for #<Balanced::Account:0x00000004a1db38> from .../gems/balanced-0.2.5/lib/balanced/resources.rb:67:in
promote_to_merchant'
from (irb):52
from.../gems/railties-3.2.3/lib/rails/commands/console.rb:47:in start' from .../gems/railties-3.2.3/lib/rails/commands/console.rb:8:in
start'
from .../gems/railties-3.2.3/lib/rails/commands.rb:41:in <top (required)>' from script/rails:6:in
require'
from script/rails:6:in `
The predicate methods generated from the response body actually do the opposite of what they're intended to do. I've got a fix in the branch I'm working off. Here's the broken code: https://github.com/balanced/balanced-ruby/blob/master/lib/balanced/resources/resource.rb#L137. Similar code also exists in the Balanced::Error
class, for which I also have a fix. Pushing all this stuff up soon.
There should be a class called Balanced::BankAccountVerification
however it's called Balanced::Verification
.
This is an issue because in the documentation it's called a BankAccountVerification
Reflection is used to create the _uri methods. Inheriting from Balanced::Card
cause excpetions when creating a new instances.
class MyCreditCard < Balanced::Card
end
MyCreditCard.new(valid_data) #=> NoMethodError: undefined method `my_credit_cards_uri' for #<Balanced::Marketplace:0xa05b8c4>
calling buyer.cards prints:
"TODO: return the pager for this class: Balanced::Card"
and returns a single card. I'm assuming at some point buyer.cards will return an array of cards, not a single card object?
The README says:
See https://www.balancedpayments.com/docs/overview?language=ruby for tutorials and documentation.
But this does not actually get you to anything involving docs of this gem, no matter how many links you follow.
Actual docs are at:
https://www.balancedpayments.com/docs/api?language=ruby
or for generated rdocs: http://rubydoc.info/gems/balanced
(thanks Remear on support IRC)
Might be a lot less confusing if you corrected the README to have these links?
The find method on Resource is implemented as an instance method when it should probably be a class method.
require 'balanced'
Balanced.configure('3bfbbc04b76711e282ba026ba7cd33d0')
marketplace = Balanced::Marketplace.my_marketplace
events = Balanced::Event.all(:limit => 2)
This example taken from https://docs.balancedpayments.com/current/api?language=ruby#list-all-events hangs and then eventually times out
Given a relatively simple file such as
require 'balanced'
key = Balanced::ApiKey.new.save
Balanced.configure(key.secret)
marketplace = Balanced::Marketplace.new.save
puts key.secret
# myapp.rb
require 'sinatra'
# erb :index2 calls upon index.erb file
get '/' do
locals = {
:marketplace_uri => marketplace.uri
}
erb :create_card, :locals => locals
end
# define email_address and card_uri with Sinatra route pattern via the params hash
# create a buyer
# return buyer uri
post '/buyer' do
email_address = params[:email_address]
card_uri = params[:card_uri]
buyer = Balanced::Marketplace.my_marketplace.create_buyer(email_address, card_uri)
return buyer.uri
end
# define account_uri and amount_in_cents
# create a debit
# return debit uri
post '/debit' do
account_uri = params[:account_uri]
amount_in_cents = params[:amount_in_cents]
debit = Balanced::Account.find(account_uri).debit(amount_in_cents)
return debit.uri
end
We get a relatively horrible stacktrace:
% ruby create_card.rb
8d055022dc3111e19b1f026ba7e5e72e
== Sinatra/1.3.2 has taken the stage on 4567 for development with backup from Mongrel
ArgumentError - tried to create Proc object without a block:
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1197:in `define_method'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1197:in `generate_method'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1206:in `compile!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1186:in `route'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1168:in `get'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1602:in `block (2 levels) in delegate'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced.rb:67:in `method_missing'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/pager.rb:149:in `load_from'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/pager.rb:100:in `load!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/pager.rb:53:in `each'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/resources/resource.rb:174:in `to_a'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/resources/resource.rb:174:in `all'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/resources/merchant.rb:9:in `me'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/balanced-0.3.9/lib/balanced/resources/marketplace.rb:12:in `my_marketplace'
create_card.rb:26:in `block in <main>'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1212:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:1212:in `block in compile!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:in `[]'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:in `block (3 levels) in route!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:801:in `route_eval'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:785:in `block (2 levels) in route!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:822:in `block in process_route'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:820:in `catch'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:820:in `process_route'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:784:in `block in route!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:783:in `each'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:783:in `route!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:886:in `dispatch!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:719:in `block in call!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:in `block in invoke'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:in `catch'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:871:in `invoke'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:719:in `call!'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/base.rb:705:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-protection-1.2.0/lib/rack/protection/path_traversal.rb:16:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-protection-1.2.0/lib/rack/protection/json_csrf.rb:17:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-protection-1.2.0/lib/rack/protection/base.rb:47:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-protection-1.2.0/lib/rack/protection/xss_header.rb:22:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/logger.rb:15:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/head.rb:9:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call'
/Users/marshall/.rvm/gems/ruby-1.9.3-p194/gems/sinatra-1.3.2/lib/sinatra/showexceptions.rb:21:in `call'
We have a new Customer resource.
With a customer you should be able to debit
, credit
, as well as add_card
and add_bank_account
. A customer should be able to tell you their active_card
and active_bank_account
.
account created does not have role 'merchant' (see https://support.balancedpayments.com/tickets/1221 ):
merchant_data = {
type: "person",
name: "Bob Example",
street_address: "123 Example Road, Chicago IL",
postal_code: 60201,
country: "USA",
dob: "1950-10",
phone_number: "3124232431"
}
merchant_name = "Bob Example"
merchant = Balanced::Marketplace.my_marketplace.create_merchant(
'[email protected]', merchant_data, nil, merchant_name)
merchant.roles
if a bank account is provided the account is properly created as a merchant.
equivalent python client call creates account with role 'merchant'.
A valid card should only be able to exist once on an account.
If you tokenize and try to associate the card again a 409 logical error should be raised. If you try to add a card that already exists but the card currently associated the new card should be added the same as any other card.
Add ruby 2.0.0 to the .travis.yml
I noticed that if I pass in basic auth to a request for an API key, it doesn't return the nested merchant object. Not sure if this is on purpose or an error. I found it surprising.
$ curl -X POST https://api.balancedpayments.com/v1/api_keys
{
"merchant": {
"phone_number": "+16505551212",
"city": "Nowhere",
"marketplace": null,
"name": "William Henry Cavendish III",
"email_address": "[email protected]",
"created_at": "2012-06-10T05:34:25.850863Z",
"uri": "/v1/merchants/TEST-MR7kCvuPrSWRASw1b8pG9t02",
"accounts_uri": "/v1/merchants/TEST-MR7kCvuPrSWRASw1b8pG9t02/accounts",
"meta": {},
"postal_code": "90210",
"country_code": "USA",
"type": "person",
"balance": 0,
"api_keys_uri": "/v1/merchants/TEST-MR7kCvuPrSWRASw1b8pG9t02/api_keys",
"id": "TEST-MR7kCvuPrSWRASw1b8pG9t02",
"street_address": "123 Fake St"
},
"secret": "f113279eb2bd11e1aed5026ba7e5e72e",
"meta": {},
"created_at": "2012-06-10T05:34:26.096824Z",
"uri": "/v1/api_keys/AK7kTVlEtm2mM12FuhIPaPw2",
"id": "AK7kTVlEtm2mM12FuhIPaPw2"
}%
$ curl -X POST https://api.balancedpayments.com/v1/api_keys -uf113279eb2bd11e1aed5026ba7e5e72e:
{
"created_at": "2012-06-10T05:34:41.655117Z",
"meta": {},
"id": "AK7CoS9SehlLsaOILX7qkAUF",
"secret": "fa59350ab2bd11e1a8a6026ba7e239a9",
"uri": "/v1/api_keys/AK7CoS9SehlLsaOILX7qkAUF"
}%
https://github.com/balanced/balanced-ruby/blob/master/lib/balanced/resources/bank_account.rb#L37
It is not parsed out of the options dict.
A work around exists:
credit = Balanced::Credit.new(
:amount => amount_in_cents,
:appears_on_statement_as => 'MIKES TACOS',
:account_uri => merchant.uri
).save
I'd like to be able to specify open and read request timeout values as configuration options. It would also be nice to be able to do it on a per-request basis, but I can live without that.
ruby-1.9.2-p180 :001 > Balanced::Transaction.all
NoMethodError: undefined method merge!' for nil:NilClass from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/pager.rb:142:in
load_from'
from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/pager.rb:84:in next' from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/pager.rb:64:in
block in each'
from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/pager.rb:59:in loop' from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/pager.rb:59:in
each'
from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/resources/resource.rb:163:in to_a' from /home/harry/.rvm/gems/ruby-1.9.2-p180/gems/balanced-0.3.5/lib/balanced/resources/resource.rb:163:in
all'
I'd like to specify my own Logger instance as a configuration option.
account = Balanced::Account.find(account_uri)
credit = account.credit(
amount: amount, # in cents
description: "Payout to #{a.name}",
appears_on_statement_as: "Ivy Payments"
)
puts credit.attributes['appears_on_statement_as'] # returns nil
checking the logs in the dashboard, I see that the request contains :appears_on_statement_as but the response does not.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.