balanced 0.3.11 → 0.5.1
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 +1 -0
- data/README.md +6 -0
- data/examples/examples.rb +37 -7
- data/lib/balanced.rb +2 -1
- data/lib/balanced/client.rb +25 -7
- data/lib/balanced/error.rb +19 -4
- data/lib/balanced/resources/account.rb +13 -15
- data/lib/balanced/resources/bank_account.rb +33 -6
- data/lib/balanced/resources/card.rb +17 -4
- data/lib/balanced/resources/credit.rb +32 -5
- data/lib/balanced/resources/debit.rb +2 -0
- data/lib/balanced/resources/hold.rb +9 -1
- data/lib/balanced/resources/marketplace.rb +119 -3
- data/lib/balanced/resources/merchant.rb +1 -1
- data/lib/balanced/resources/resource.rb +35 -10
- data/lib/balanced/version.rb +1 -1
- data/spec/balanced/error_spec.rb +42 -0
- data/spec/balanced/resources/account_spec.rb +75 -102
- data/spec/balanced/resources/bank_account_spec.rb +91 -0
- data/spec/balanced/resources/credit_spec.rb +60 -0
- data/spec/balanced/resources/hold_spec.rb +6 -5
- data/spec/balanced/resources/marketplace_spec.rb +115 -6
- data/spec/balanced/resources/merchant_spec.rb +6 -0
- data/spec/balanced/resources/resource_spec.rb +43 -0
- data/spec/balanced/resources/transactions_spec.rb +8 -5
- data/spec/balanced_spec.rb +20 -1
- data/spec/spec_helper.rb +18 -0
- metadata +14 -5
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -55,6 +55,12 @@ spec/cassettes. To clear them and regenerate:
|
|
55
55
|
$ rm -rf spec/cassettes
|
56
56
|
|
57
57
|
|
58
|
+
### Issues
|
59
|
+
|
60
|
+
All issues should be documented at
|
61
|
+
[balanced-ruby/issues](https://github.com/balanced/balanced-ruby/issues)
|
62
|
+
|
63
|
+
|
58
64
|
### Building Documentation
|
59
65
|
|
60
66
|
Documentation is built using YARD - http://rubydoc.info/docs/yard
|
data/examples/examples.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
cwd = File.dirname(File.dirname(File.absolute_path(__FILE__)))
|
2
|
+
$:.unshift(cwd + "/lib")
|
2
3
|
require 'balanced'
|
3
4
|
|
4
5
|
begin
|
@@ -7,9 +8,9 @@ rescue NameError
|
|
7
8
|
raise "wtf"
|
8
9
|
end
|
9
10
|
|
10
|
-
host = ENV
|
11
|
+
host = ENV.fetch('BALANCED_HOST') { nil }
|
11
12
|
options = {}
|
12
|
-
if host
|
13
|
+
if host
|
13
14
|
options[:scheme] = 'http'
|
14
15
|
options[:host] = host
|
15
16
|
options[:port] = 5000
|
@@ -79,11 +80,11 @@ refund = debit.refund() # the full amount!
|
|
79
80
|
puts "ok, we have a merchant that's signing up, let's create an account for them " \
|
80
81
|
"first, lets create their bank account."
|
81
82
|
|
82
|
-
bank_account =
|
83
|
+
bank_account = marketplace.create_bank_account(
|
83
84
|
:account_number => "1234567890",
|
84
85
|
:bank_code => "12",
|
85
86
|
:name => "Jack Q Merchant",
|
86
|
-
)
|
87
|
+
)
|
87
88
|
|
88
89
|
merchant = marketplace.create_merchant(
|
89
90
|
:email_address => "merchant@example.org",
|
@@ -100,9 +101,9 @@ merchant = marketplace.create_merchant(
|
|
100
101
|
:name => "Jack Q Merchant",
|
101
102
|
)
|
102
103
|
|
103
|
-
puts "oh our buyer is interested in buying something for
|
104
|
+
puts "oh our buyer is interested in buying something for 530.00$"
|
104
105
|
another_debit = buyer.debit(
|
105
|
-
:amount =>
|
106
|
+
:amount => 53000,
|
106
107
|
:appears_on_statement_as => "MARKETPLACE.COM"
|
107
108
|
)
|
108
109
|
|
@@ -127,3 +128,32 @@ puts "invalidating a bank account"
|
|
127
128
|
bank_account.invalidate
|
128
129
|
|
129
130
|
raise "This card is INCORRECTLY VALID" if bank_account.is_valid
|
131
|
+
|
132
|
+
puts "let's create a bank account not associated to an account"
|
133
|
+
bank_account = Balanced::BankAccount.new(
|
134
|
+
:account_number => "9876543210",
|
135
|
+
:routing_number => "021000021",
|
136
|
+
:name => "Jake Skellington",
|
137
|
+
:type => "checking"
|
138
|
+
).save
|
139
|
+
|
140
|
+
puts "now let's credit it, the super-simple way"
|
141
|
+
credit = bank_account.credit(
|
142
|
+
:amount => 500
|
143
|
+
)
|
144
|
+
|
145
|
+
raise "Incorrect value for credit" if credit.amount != 500
|
146
|
+
|
147
|
+
puts "That was still too hard -- let's credit without creating a bank account first"
|
148
|
+
credit = Balanced::Credit.new(
|
149
|
+
:amount => 700,
|
150
|
+
:description => "Amazing",
|
151
|
+
:bank_account => {
|
152
|
+
:account_number => "55555555",
|
153
|
+
:bank_code => "021000021",
|
154
|
+
:name => "Wanda Wandy",
|
155
|
+
:type => "checking"
|
156
|
+
}
|
157
|
+
).save
|
158
|
+
raise "OOPS -- that was hard after all" if (credit.amount != 700 or
|
159
|
+
credit.created_at.nil?)
|
data/lib/balanced.rb
CHANGED
@@ -25,7 +25,8 @@ module Balanced
|
|
25
25
|
attr_accessor :config
|
26
26
|
|
27
27
|
def configure(api_key=nil, options={})
|
28
|
-
@
|
28
|
+
@config = @config.merge(options)
|
29
|
+
@client = Balanced::Client.new(api_key, @config)
|
29
30
|
end
|
30
31
|
|
31
32
|
def is_configured_with_api_key?
|
data/lib/balanced/client.rb
CHANGED
@@ -16,7 +16,8 @@ module Balanced
|
|
16
16
|
:logging_level => 'WARN',
|
17
17
|
:connection_timeout => 2,
|
18
18
|
:read_timeout => 5,
|
19
|
-
:logger => nil
|
19
|
+
:logger => nil,
|
20
|
+
:ssl_verify => true
|
20
21
|
}
|
21
22
|
|
22
23
|
attr_reader :conn
|
@@ -43,6 +44,9 @@ module Balanced
|
|
43
44
|
:request => {
|
44
45
|
:open_timeout => config[:connection_timeout],
|
45
46
|
:timeout => config[:read_timeout]
|
47
|
+
},
|
48
|
+
:ssl => {
|
49
|
+
:verify => @config[:ssl_verify] # Only set this to false for testing
|
46
50
|
}
|
47
51
|
}
|
48
52
|
@conn = Faraday.new(url, options) do |cxn|
|
@@ -63,20 +67,34 @@ module Balanced
|
|
63
67
|
#end
|
64
68
|
|
65
69
|
def url
|
66
|
-
|
67
|
-
end
|
70
|
+
builder = (config[:scheme] == 'http') ? URI::HTTP : URI::HTTPS
|
68
71
|
|
69
|
-
|
72
|
+
builder.build ({:host => config[:host],
|
73
|
+
:port => config[:port],
|
74
|
+
:scheme => config[:scheme]})
|
75
|
+
end
|
70
76
|
|
71
77
|
def method_missing(method, *args, &block)
|
72
|
-
|
73
|
-
when :get, :post, :put, :delete
|
78
|
+
if is_http_method? method
|
74
79
|
conn.basic_auth(api_key, '') unless api_key.nil?
|
75
80
|
conn.send method, *args
|
76
81
|
else
|
77
|
-
super
|
82
|
+
super method, *args, &block
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
86
|
+
private
|
87
|
+
|
88
|
+
def is_http_method? method
|
89
|
+
[:get, :post, :put, :delete].include? method
|
90
|
+
end
|
91
|
+
|
92
|
+
def respond_to?(method, include_private = false)
|
93
|
+
if is_http_method? method
|
94
|
+
true
|
95
|
+
else
|
96
|
+
super method, include_private
|
97
|
+
end
|
98
|
+
end
|
81
99
|
end
|
82
100
|
end
|
data/lib/balanced/error.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
module Balanced
|
2
2
|
|
3
|
-
# Custom error class for rescuing from all Balanced errors
|
4
|
-
class Error < StandardError
|
3
|
+
# Custom error class for rescuing from all API response-related Balanced errors
|
4
|
+
class Error < ::StandardError
|
5
5
|
attr_reader :response
|
6
6
|
|
7
|
+
# @param [Hash] response the decoded json response body
|
7
8
|
def initialize(response)
|
8
9
|
@response = response
|
9
10
|
super error_message
|
10
11
|
end
|
11
12
|
|
13
|
+
# @return [Hash]
|
12
14
|
def body
|
13
|
-
|
15
|
+
@body ||= begin
|
16
|
+
return {} unless response[:body]
|
17
|
+
Utils.hash_with_indifferent_read_access(response[:body])
|
18
|
+
end
|
14
19
|
end
|
15
20
|
|
16
21
|
def error_message
|
@@ -26,12 +31,22 @@ module Balanced
|
|
26
31
|
body.keys.each do |name|
|
27
32
|
self.class.instance_eval {
|
28
33
|
define_method(name) { body[name] } # Get.
|
29
|
-
define_method("#{name}?") { !!body[name]
|
34
|
+
define_method("#{name}?") { !!body[name] } # Present.
|
30
35
|
}
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
34
39
|
|
40
|
+
# General error class for non API response exceptions
|
41
|
+
class StandardError < Error
|
42
|
+
attr_reader :message
|
43
|
+
alias :error_message :message
|
44
|
+
|
45
|
+
def initialize(message)
|
46
|
+
@message = message
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
35
50
|
class MoreInformationRequired < Error
|
36
51
|
def redirect_uri
|
37
52
|
response.headers['Location']
|
@@ -29,9 +29,11 @@ module Balanced
|
|
29
29
|
#
|
30
30
|
# @return [Debit]
|
31
31
|
def debit *args
|
32
|
+
warn_on_positional args
|
33
|
+
|
32
34
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
33
35
|
amount = args[0] || options.fetch(:amount) { nil }
|
34
|
-
|
36
|
+
appears_on_statement_as = args[1] || options.fetch(:appears_on_statement_as) { nil }
|
35
37
|
hold_uri = args[2] || options.fetch(:hold_uri) { nil }
|
36
38
|
meta = args[3] || options.fetch(:meta) { nil }
|
37
39
|
description = args[4] || options.fetch(:description) { nil }
|
@@ -40,7 +42,7 @@ module Balanced
|
|
40
42
|
debit = Debit.new(
|
41
43
|
:uri => self.debits_uri,
|
42
44
|
:amount => amount,
|
43
|
-
:appears_on_statement_as =>
|
45
|
+
:appears_on_statement_as => appears_on_statement_as,
|
44
46
|
:hold_uri => hold_uri,
|
45
47
|
:meta => meta,
|
46
48
|
:description => description,
|
@@ -59,6 +61,8 @@ module Balanced
|
|
59
61
|
# @return [Hold] A Hold representing the reservation of funds from
|
60
62
|
# this Account to your Marketplace.
|
61
63
|
def hold *args
|
64
|
+
warn_on_positional args
|
65
|
+
|
62
66
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
63
67
|
amount = args[0] || options.fetch(:amount) { }
|
64
68
|
meta = args[1] || options.fetch(:meta) { nil }
|
@@ -81,20 +85,14 @@ module Balanced
|
|
81
85
|
# @return [Credit] A Credit representing the transfer of funds from
|
82
86
|
# your Marketplace to this Account.
|
83
87
|
def credit *args
|
84
|
-
|
85
|
-
amount = args[0] || options.fetch(:amount) { }
|
86
|
-
description = args[1] || options.fetch(:description) { nil }
|
87
|
-
meta = args[2] || options.fetch(:meta) { nil }
|
88
|
-
destination_uri = args[3] || options.fetch(:destination_uri) { nil }
|
88
|
+
warn_on_positional args
|
89
89
|
|
90
|
-
|
91
|
-
:
|
92
|
-
|
93
|
-
:
|
94
|
-
|
95
|
-
|
96
|
-
)
|
97
|
-
credit.save
|
90
|
+
if args.last.is_a? Hash
|
91
|
+
args.last.merge! uri: self.credits_uri
|
92
|
+
else
|
93
|
+
args << { uri: self.credits_uri }
|
94
|
+
end
|
95
|
+
Credit.new(*args).save
|
98
96
|
end
|
99
97
|
|
100
98
|
# Associates the Card represented by +card_uri+ with this Account.
|
@@ -7,6 +7,19 @@ module Balanced
|
|
7
7
|
class BankAccount
|
8
8
|
include Balanced::Resource
|
9
9
|
|
10
|
+
def self.has_account?
|
11
|
+
self.respond_to?('account') && !self.account.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.uri
|
15
|
+
# Override the default nesting -- bank accounts can be toplevel now
|
16
|
+
if !self.has_account?
|
17
|
+
self.collection_path
|
18
|
+
else
|
19
|
+
self.class.uri
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
10
23
|
def initialize attributes = {}
|
11
24
|
Balanced::Utils.stringify_keys! attributes
|
12
25
|
unless attributes.has_key? 'uri'
|
@@ -21,25 +34,39 @@ module Balanced
|
|
21
34
|
# the +domain_name+ property from your Marketplace.
|
22
35
|
# @return [Debit]
|
23
36
|
def debit *args
|
37
|
+
warn_on_positional args
|
38
|
+
|
24
39
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
25
40
|
amount = args[0] || options.fetch(:amount) { nil }
|
26
|
-
|
41
|
+
appears_on_statement_as = args[1] || options.fetch(:appears_on_statement_as) { nil }
|
27
42
|
meta = args[2] || options.fetch(:meta) { nil }
|
28
43
|
description = args[3] || options.fetch(:description) { nil }
|
29
44
|
|
30
|
-
self.account.debit(amount,
|
45
|
+
self.account.debit(amount, appears_on_statement_as, meta, description, self.uri)
|
31
46
|
end
|
32
47
|
|
33
|
-
# Creates a Credit of funds from your Marketplace's escrow account to this
|
48
|
+
# Creates a Credit of funds from your Marketplace's escrow account to this
|
49
|
+
# Account.
|
34
50
|
#
|
35
51
|
# @return [Credit]
|
36
52
|
def credit *args
|
53
|
+
warn_on_positional args
|
54
|
+
|
37
55
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
38
56
|
amount = args[0] || options.fetch(:amount) { nil }
|
39
57
|
description = args[1] || options.fetch(:description) { nil }
|
40
|
-
|
41
|
-
|
42
|
-
|
58
|
+
if !self.class.has_account?
|
59
|
+
Credit.new(
|
60
|
+
:amount => amount,
|
61
|
+
:description => description,
|
62
|
+
:uri => self.credits_uri,
|
63
|
+
).save
|
64
|
+
else
|
65
|
+
meta = args[2] || options.fetch(:meta) { nil }
|
66
|
+
appears_on_statement_as = args[3] || options.fetch(:appears_on_statement_as) { nil }
|
67
|
+
destination_url = args[4] || options.fetch(:destination_uri) { self.uri }
|
68
|
+
self.account.credit(amount, meta, description, destination_uri, appears_on_statement_as)
|
69
|
+
end
|
43
70
|
end
|
44
71
|
|
45
72
|
def invalidate
|
@@ -20,25 +20,38 @@ module Balanced
|
|
20
20
|
#
|
21
21
|
# @return [Debit]
|
22
22
|
def debit *args
|
23
|
+
warn_on_positional args
|
23
24
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
24
25
|
amount = args[0] || options.fetch(:amount) { nil }
|
25
26
|
appears_on_statement_as = args[1] || options.fetch(:appears_on_statement_as) { nil }
|
26
|
-
|
27
|
+
hold_uri = args[2] || options.fetch(:hold_uri) { nil }
|
27
28
|
meta = args[3] || options.fetch(:meta) { nil }
|
28
29
|
description = args[3] || options.fetch(:description) { nil }
|
29
30
|
|
30
|
-
self.account.debit(
|
31
|
+
self.account.debit(
|
32
|
+
:amount => amount,
|
33
|
+
:appears_on_statement_as => appears_on_statement_as,
|
34
|
+
:hold_uri => hold_uri,
|
35
|
+
:meta => meta,
|
36
|
+
:description => description,
|
37
|
+
:source_uri => self.uri
|
38
|
+
)
|
31
39
|
end
|
32
40
|
|
33
41
|
# Creates a Hold of funds from this Card to your Marketplace.
|
34
42
|
#
|
35
43
|
# @return [Hold]
|
36
44
|
def hold *args
|
45
|
+
warn_on_positional args
|
37
46
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
38
47
|
amount = args[0] || options.fetch(:amount) { nil }
|
39
|
-
meta = args[
|
48
|
+
meta = args[1] || options.fetch(:meta) { nil }
|
40
49
|
|
41
|
-
self.account.hold(
|
50
|
+
self.account.hold(
|
51
|
+
:amount => amount,
|
52
|
+
:meta => meta,
|
53
|
+
:source_uri => self.uri
|
54
|
+
)
|
42
55
|
end
|
43
56
|
|
44
57
|
def invalidate
|
@@ -8,13 +8,40 @@ module Balanced
|
|
8
8
|
#
|
9
9
|
class Credit
|
10
10
|
include Balanced::Resource
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
|
12
|
+
def initialize *args
|
13
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
14
|
+
uri = options.fetch(:uri) { self.class.uri }
|
15
|
+
bank_account = options.fetch(:bank_account) {}
|
16
|
+
amount = args[0] || options.fetch(:amount) { }
|
17
|
+
description = args[1] || options.fetch(:description) { nil }
|
18
|
+
|
19
|
+
unless bank_account.nil?
|
20
|
+
# Accountless bank account
|
21
|
+
attributes = {
|
22
|
+
uri: uri,
|
23
|
+
amount: amount,
|
24
|
+
description: description,
|
25
|
+
bank_account: bank_account,
|
26
|
+
meta: nil
|
27
|
+
}
|
28
|
+
else
|
29
|
+
meta = args[2] || options.fetch(:meta) { nil }
|
30
|
+
destination_uri = args[3] || options.fetch(:destination_uri) { nil }
|
31
|
+
appears_on_statement_as = args[4] || options.fetch(:appears_on_statement_as) { nil }
|
32
|
+
attributes = {
|
33
|
+
uri: uri,
|
34
|
+
amount: amount,
|
35
|
+
meta: meta,
|
36
|
+
description: description,
|
37
|
+
destination_uri: destination_uri,
|
38
|
+
appears_on_statement_as: appears_on_statement_as
|
39
|
+
}
|
15
40
|
end
|
41
|
+
|
42
|
+
Balanced::Utils.stringify_keys! attributes
|
43
|
+
|
16
44
|
super attributes
|
17
45
|
end
|
18
46
|
end
|
19
47
|
end
|
20
|
-
|
@@ -28,6 +28,8 @@ module Balanced
|
|
28
28
|
#
|
29
29
|
# @return [Refund]
|
30
30
|
def refund *args
|
31
|
+
warn_on_positional args
|
32
|
+
|
31
33
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
32
34
|
amount = args[0] || options.fetch(:amount) { nil }
|
33
35
|
description = args[1] || options.fetch(:description) { nil }
|
@@ -38,6 +38,8 @@ module Balanced
|
|
38
38
|
#
|
39
39
|
# @return [Debit]
|
40
40
|
def capture *args
|
41
|
+
warn_on_positional args
|
42
|
+
|
41
43
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
42
44
|
amount = args[0] || options.fetch(:amount) { nil }
|
43
45
|
appears_on_statement_as = args[1] || options.fetch(:appears_on_statement_as) { nil }
|
@@ -45,7 +47,13 @@ module Balanced
|
|
45
47
|
description = args[3] || options.fetch(:description) { nil }
|
46
48
|
|
47
49
|
amount ||= self.amount
|
48
|
-
self.account.debit(
|
50
|
+
self.account.debit(
|
51
|
+
:amount => amount,
|
52
|
+
:appears_on_statement_as => appears_on_statement_as,
|
53
|
+
:hold_uri => self.uri,
|
54
|
+
:meta => meta,
|
55
|
+
:description => description
|
56
|
+
)
|
49
57
|
end
|
50
58
|
|
51
59
|
end
|