balanced 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/CONTRIBUTORS +4 -0
- data/Gemfile +3 -0
- data/Guardfile +7 -0
- data/README.md +31 -2
- data/balanced.gemspec +4 -1
- data/examples/examples.rb +18 -2
- data/lib/balanced.rb +16 -25
- data/lib/balanced/client.rb +16 -39
- data/lib/balanced/resources.rb +13 -241
- data/lib/balanced/resources/account.rb +134 -0
- data/lib/balanced/resources/api_key.rb +18 -0
- data/lib/balanced/resources/bank_account.rb +34 -0
- data/lib/balanced/resources/card.rb +34 -0
- data/lib/balanced/resources/credit.rb +20 -0
- data/lib/balanced/resources/debit.rb +42 -0
- data/lib/balanced/resources/hold.rb +42 -0
- data/lib/balanced/resources/marketplace.rb +77 -0
- data/lib/balanced/resources/merchant.rb +25 -0
- data/lib/balanced/resources/refund.rb +21 -0
- data/lib/balanced/resources/resource.rb +130 -0
- data/lib/balanced/resources/transaction.rb +18 -0
- data/lib/balanced/version.rb +1 -1
- data/spec/balanced/resources/account_spec.rb +422 -0
- data/spec/balanced/resources/api_key_spec.rb +55 -0
- data/spec/balanced/resources/marketplace_spec.rb +97 -0
- data/spec/balanced_spec.rb +73 -12
- data/spec/client_spec.rb +2 -2
- data/spec/spec_helper.rb +24 -0
- data/spec/utils_spec.rb +2 -2
- metadata +85 -7
- data/lib/balanced/base.rb +0 -129
- data/spec/api_key_spec.rb +0 -20
@@ -0,0 +1,134 @@
|
|
1
|
+
module Balanced
|
2
|
+
# An Account represents a user within your Marketplace. An Account can have
|
3
|
+
# two +roles+. If the Account has the +buyer+ role then you may create
|
4
|
+
# Debits using this Account. If they have the +merchant+ role then you may
|
5
|
+
# create Credits to transfer funds to this Account.
|
6
|
+
#
|
7
|
+
class Account
|
8
|
+
include Balanced::Resource
|
9
|
+
|
10
|
+
def initialize attributes = {}
|
11
|
+
Balanced::Utils.stringify_keys! attributes
|
12
|
+
unless attributes.has_key? 'uri'
|
13
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
14
|
+
end
|
15
|
+
super attributes
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns a new Debit that represents a flow of money from this
|
19
|
+
# Account to your Marketplace.
|
20
|
+
#
|
21
|
+
# @return [Debit]
|
22
|
+
def debit (amount=nil,
|
23
|
+
appears_on_statement_as=nil,
|
24
|
+
hold_uri=nil,
|
25
|
+
meta={},
|
26
|
+
description=nil,
|
27
|
+
source_uri=nil)
|
28
|
+
debit = Debit.new(
|
29
|
+
:uri => self.debits_uri,
|
30
|
+
:amount => amount,
|
31
|
+
:appears_on_statement_as => appears_on_statement_as,
|
32
|
+
:hold_uri => hold_uri,
|
33
|
+
:meta => meta,
|
34
|
+
:description => description,
|
35
|
+
:source_uri => source_uri,
|
36
|
+
)
|
37
|
+
debit.save
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a new Hold that represents a reservation of money on this
|
41
|
+
# Account which can be transferred via a Debit to your Marketplace
|
42
|
+
# up to 7 days later.
|
43
|
+
#
|
44
|
+
# @param [String] source_uri A specific funding source such as a Card
|
45
|
+
# associated with this account. If not specified the most recently
|
46
|
+
# added Card is used.
|
47
|
+
# @return [Hold] A Hold representing the reservation of funds from
|
48
|
+
# this Account to your Marketplace.
|
49
|
+
def hold amount, meta={}, source_uri=nil
|
50
|
+
hold = Hold.new(
|
51
|
+
:uri => self.holds_uri,
|
52
|
+
:amount => amount,
|
53
|
+
:meta => meta,
|
54
|
+
:source_uri => source_uri,
|
55
|
+
)
|
56
|
+
hold.save
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns a new Credit representing a transfer of funds from your
|
60
|
+
# Marketplace to this Account.
|
61
|
+
#
|
62
|
+
# @param [String] destination_uri A specific funding destination such as
|
63
|
+
# a BankAccount already associated with this account.
|
64
|
+
# @return [Credit] A Credit representing the transfer of funds from
|
65
|
+
# your Marketplace to this Account.
|
66
|
+
def credit amount, description=nil, meta={}, destination_uri=nil
|
67
|
+
credit = Credit.new(
|
68
|
+
:uri => self.credits_uri,
|
69
|
+
:amount => amount,
|
70
|
+
:meta => meta,
|
71
|
+
:description => description,
|
72
|
+
:destination_uri => destination_uri,
|
73
|
+
)
|
74
|
+
credit.save
|
75
|
+
end
|
76
|
+
|
77
|
+
# Associates the Card represented by +card_uri+ with this Account.
|
78
|
+
#
|
79
|
+
# @return [Card]
|
80
|
+
def add_card card_uri
|
81
|
+
self.card_uri = card_uri
|
82
|
+
save
|
83
|
+
end
|
84
|
+
|
85
|
+
# Associates the BankAccount represented by +bank_account_uri+ with this
|
86
|
+
# Account.
|
87
|
+
#
|
88
|
+
# @return [BankAccount]
|
89
|
+
def add_bank_account bank_account_uri
|
90
|
+
self.bank_account_uri = bank_account_uri
|
91
|
+
save
|
92
|
+
end
|
93
|
+
|
94
|
+
# Adds the role Merchant to this Account.
|
95
|
+
#
|
96
|
+
# The merchant data for a *person* should look like:
|
97
|
+
#
|
98
|
+
# {
|
99
|
+
# :type => "person",
|
100
|
+
# :name => "William James", # Legal name
|
101
|
+
# :street_address => "167 West 74th Street",
|
102
|
+
# :postal_code => "10023",
|
103
|
+
# :country_code => "USA", # ISO 3166-1 alpha-3
|
104
|
+
# :dob => "1842-01",
|
105
|
+
# :phone_number => "+16505551234"
|
106
|
+
# }
|
107
|
+
#
|
108
|
+
# For a *business*, the payload should look like:
|
109
|
+
#
|
110
|
+
# {
|
111
|
+
# :name => "Levain Bakery",
|
112
|
+
# :tax_id => "253912384", # Optional
|
113
|
+
# :street_address => "167 West 74th Street",
|
114
|
+
# :postal_code => "10023",
|
115
|
+
# :phone_number => "+16505551234",
|
116
|
+
# :country_code => "USA", # ISO 3166-1 alpha-3
|
117
|
+
# :person => {
|
118
|
+
# :name => "William James", # Legal name
|
119
|
+
# :tax_id => "393483992", # Optional
|
120
|
+
# :street_address => "167 West 74th Street", # Home address
|
121
|
+
# :postal_code => "10023",
|
122
|
+
# :dob => "1842-01-01",
|
123
|
+
# :phone_number => "+16505551234",
|
124
|
+
# :country_code => "USA" # ISO 3166-1 alpha-3
|
125
|
+
# }
|
126
|
+
# }
|
127
|
+
#
|
128
|
+
def promote_to_merchant merchant_data
|
129
|
+
self.merchant = merchant_data
|
130
|
+
save
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Balanced
|
2
|
+
|
3
|
+
# Your ApiKey is used to authenticate when performing operations on the
|
4
|
+
# Balanced API.
|
5
|
+
#
|
6
|
+
# *NOTE:* Never give out or expose your ApiKey. You may POST to this
|
7
|
+
# endpoint to create new ApiKeys and then DELETE any old keys.
|
8
|
+
class ApiKey
|
9
|
+
include Balanced::Resource
|
10
|
+
|
11
|
+
def save
|
12
|
+
Balanced.configure nil
|
13
|
+
super
|
14
|
+
end
|
15
|
+
def wut; end;
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A BankAccount is both a source, and a destination of, funds. You may
|
3
|
+
# create Debits and Credits to and from, this funding source.
|
4
|
+
#
|
5
|
+
# *NOTE:* The BankAccount resource does not support creating a Hold.
|
6
|
+
#
|
7
|
+
class BankAccount
|
8
|
+
include Balanced::Resource
|
9
|
+
|
10
|
+
def initialize attributes = {}
|
11
|
+
Balanced::Utils.stringify_keys! attributes
|
12
|
+
unless attributes.has_key? 'uri'
|
13
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
14
|
+
end
|
15
|
+
super attributes
|
16
|
+
end
|
17
|
+
|
18
|
+
# Creates a Debit of funds from this BankAccount to your Marketplace.
|
19
|
+
#
|
20
|
+
# @param [String] appears_on_statement_as If nil then Balanced will use
|
21
|
+
# the +domain_name+ property from your Marketplace.
|
22
|
+
# @return [Debit]
|
23
|
+
def debit amount, appears_on_statement_as=nil, meta={}, description=nil
|
24
|
+
self.account.debit(amount, appears_on_statement_as, meta, description, self.uri)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a Credit of funds from your Marketplace to this Account.
|
28
|
+
#
|
29
|
+
# @return [Credit]
|
30
|
+
def credit amount, description=nil, meta={}
|
31
|
+
self.account.credit(amount, description, meta, self.uri)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A card represents a source of funds for an Account. You may Hold or Debit
|
3
|
+
# funds from the account associated with the Card.
|
4
|
+
#
|
5
|
+
class Card
|
6
|
+
include Balanced::Resource
|
7
|
+
|
8
|
+
def initialize attributes = {}
|
9
|
+
Balanced::Utils.stringify_keys! attributes
|
10
|
+
unless attributes.has_key? 'uri'
|
11
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
12
|
+
end
|
13
|
+
super attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
# Creates a Debit of funds from this Card to your Marketplace.
|
17
|
+
#
|
18
|
+
# If +appears_on_statement_as+ is nil, then Balanced will use the
|
19
|
+
# +domain_name+ property from your Marketplace.
|
20
|
+
#
|
21
|
+
# @return [Debit]
|
22
|
+
def debit amount=nil, appears_on_statement_as=nil, holds_uri=nil, meta={}, description=nil
|
23
|
+
self.account.debit(amount, appears_on_statement_as, holds_uri, meta, description, self.uri)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Creates a Hold of funds from this Card to your Marketplace.
|
27
|
+
#
|
28
|
+
# @return [Hold]
|
29
|
+
def hold amount=nil, meta=nil
|
30
|
+
self.account.hold(amount, meta, self.uri)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A Credit represents a transfer of funds from your Marketplace to a
|
3
|
+
# Merchant's Account within your Marketplace.
|
4
|
+
#
|
5
|
+
# By default, a Credit is sent to the most recently added funding
|
6
|
+
# destination associated with an Account. You may specify a specific
|
7
|
+
# funding source.
|
8
|
+
#
|
9
|
+
class Credit
|
10
|
+
include Balanced::Resource
|
11
|
+
def initialize attributes = {}
|
12
|
+
Balanced::Utils.stringify_keys! attributes
|
13
|
+
unless attributes.has_key? 'uri'
|
14
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
15
|
+
end
|
16
|
+
super attributes
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A Debit represents a transfer of funds from a buyer's Account to your
|
3
|
+
# Marketplace.
|
4
|
+
#
|
5
|
+
# A Debit may be created directly, or it will be created as a side-effect
|
6
|
+
# of capturing a Hold. If you create a Debit directly it will implicitly
|
7
|
+
# create the associated Hold if the funding source supports this.
|
8
|
+
#
|
9
|
+
# If no Hold is specified the Debit will by default be created using the
|
10
|
+
# most recently added funding source associated with the Account. You
|
11
|
+
# cannot change the funding source between creating a Hold and capturing
|
12
|
+
# it.
|
13
|
+
#
|
14
|
+
class Debit
|
15
|
+
include Balanced::Resource
|
16
|
+
|
17
|
+
def initialize attributes = {}
|
18
|
+
Balanced::Utils.stringify_keys! attributes
|
19
|
+
unless attributes.has_key? 'uri'
|
20
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
21
|
+
end
|
22
|
+
super attributes
|
23
|
+
end
|
24
|
+
|
25
|
+
# Refunds this Debit. If no amount is specified it will refund the entire
|
26
|
+
# amount of the Debit, you may create many Refunds up to the sum total
|
27
|
+
# of the original Debit's amount.
|
28
|
+
#
|
29
|
+
# @return [Refund]
|
30
|
+
def refund amount=nil, description=nil
|
31
|
+
refund = Refund.new(
|
32
|
+
:uri => self.refunds_uri,
|
33
|
+
:debit_uri => self.uri,
|
34
|
+
:amount => amount,
|
35
|
+
:description => description,
|
36
|
+
)
|
37
|
+
refund.save
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A Hold is a reservation of funds on a funding source such as a Card. This
|
3
|
+
# reservation is guaranteed until the +expires_at+ date. You may capture
|
4
|
+
# the Hold at any time before then which will create a Debit and transfer
|
5
|
+
# the funds to your Marketplace. If you do not capture the Hold it will
|
6
|
+
# be marked as invalid which is represented by the +is_void+ field being
|
7
|
+
# set to +true+.
|
8
|
+
#
|
9
|
+
# By default a Hold is created using the most recently added funding source
|
10
|
+
# on the Account. You may specify a specific funding source such as a Card
|
11
|
+
# or BankAccount uri.
|
12
|
+
#
|
13
|
+
class Hold
|
14
|
+
include Balanced::Resource
|
15
|
+
|
16
|
+
def initialize attributes = {}
|
17
|
+
Balanced::Utils.stringify_keys! attributes
|
18
|
+
unless attributes.has_key? 'uri'
|
19
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
20
|
+
end
|
21
|
+
super attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
# Cancels an active Hold.
|
25
|
+
#
|
26
|
+
def void
|
27
|
+
@is_void = true
|
28
|
+
save
|
29
|
+
end
|
30
|
+
|
31
|
+
# Captures a valid Hold and returns a Debit representing the transfer of
|
32
|
+
# funds from the buyer's Account to your Marketplace.
|
33
|
+
#
|
34
|
+
# @return [Debit]
|
35
|
+
def capture amount=nil, appears_on_statement_as=nil, meta={}, description=nil
|
36
|
+
amount ||= self.amount
|
37
|
+
self.account.debit(amount, appears_on_statement_as, self.uri, meta, description)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Balanced
|
2
|
+
#
|
3
|
+
#
|
4
|
+
class Marketplace
|
5
|
+
include Balanced::Resource
|
6
|
+
|
7
|
+
# Returns an instance representing the marketplace associated with
|
8
|
+
# the current API key.
|
9
|
+
#
|
10
|
+
# @return [Marketplace]
|
11
|
+
def self.my_marketplace
|
12
|
+
# TODO: use query
|
13
|
+
response = Balanced.get collection_path
|
14
|
+
return nil if response.body.to_s.length.zero? or response.body['total'] == 0
|
15
|
+
payload = response.body
|
16
|
+
construct_from_response payload['items'][0]
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an instance representing the marketplace associated with
|
20
|
+
# the current API key.
|
21
|
+
#
|
22
|
+
# @return [Marketplace]
|
23
|
+
def my_marketplace
|
24
|
+
self.class.my_marketplace
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a buyer Account associated with this Marketplace.
|
28
|
+
#
|
29
|
+
# @return [Account]
|
30
|
+
def create_buyer email_address, card_uri, name=nil, meta={}
|
31
|
+
account = Account.new(
|
32
|
+
:uri => self.accounts_uri,
|
33
|
+
:email_address => email_address,
|
34
|
+
:card_uri => card_uri,
|
35
|
+
:name => name,
|
36
|
+
:meta => meta,
|
37
|
+
)
|
38
|
+
account.save
|
39
|
+
end
|
40
|
+
|
41
|
+
# Creates a Merchant Account associated with this Marketplace.
|
42
|
+
#
|
43
|
+
# This method may return 300 if you have not supplied enough information
|
44
|
+
# for Balanced to identify the Merchant. You may re-submit the request
|
45
|
+
# with more information, or redirect the Merchant to the supplied url
|
46
|
+
# so they may manually sign up.
|
47
|
+
#
|
48
|
+
# When you receive a merchant_uri from balanced, just pass it in:
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# Account.create_merchant('bob@example.com', '/v1/TEST-MRxxxx')
|
52
|
+
#
|
53
|
+
# @return [Account]
|
54
|
+
def create_merchant email_address, merchant, bank_account_uri=nil, name=nil, meta={}
|
55
|
+
account_attributes = Hash.new(
|
56
|
+
:uri => self.accounts_uri,
|
57
|
+
:email_address => email_address,
|
58
|
+
:bank_account_uri => bank_account_uri,
|
59
|
+
:name => name,
|
60
|
+
:meta => meta,
|
61
|
+
)
|
62
|
+
|
63
|
+
if merchant.is_a? Hash
|
64
|
+
account_attributes[:merchant] = merchant
|
65
|
+
else
|
66
|
+
account_attributes[:merchant_uri] = merchant
|
67
|
+
end
|
68
|
+
|
69
|
+
account_attributes
|
70
|
+
account = Account.new account_attributes
|
71
|
+
account.save
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Balanced
|
2
|
+
class Merchant
|
3
|
+
include Balanced::Resource
|
4
|
+
|
5
|
+
# Returns the Merchant associated with your Marketplace.
|
6
|
+
#
|
7
|
+
# @return [Merchant]
|
8
|
+
def self.me
|
9
|
+
# TODO: use query
|
10
|
+
response = Balanced.get collection_path
|
11
|
+
return nil if response.body.to_s.length.zero? or response.body['total'] == 0
|
12
|
+
payload = response.body
|
13
|
+
construct_from_response payload['items'][0]
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the Merchant associated with your Marketplace.
|
17
|
+
#
|
18
|
+
# @return [Merchant]
|
19
|
+
def me
|
20
|
+
self.class.me
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Balanced
|
2
|
+
# A Refund represents a reversal of funds from a Debit. A Debit can have
|
3
|
+
# many Refunds associated with it up to the total amount of the original
|
4
|
+
# Debit. Funds are returned to your Marketplace's Merchant Account
|
5
|
+
# proportional to the amoun of the Refund.
|
6
|
+
#
|
7
|
+
class Refund
|
8
|
+
include Balanced::Resource
|
9
|
+
|
10
|
+
def initialize attributes = {}
|
11
|
+
Balanced::Utils.stringify_keys! attributes
|
12
|
+
unless attributes.has_key? 'uri'
|
13
|
+
attributes['uri'] = Balanced::Marketplace.my_marketplace.send(self.class.collection_name + '_uri')
|
14
|
+
end
|
15
|
+
super attributes
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|