braintree 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/braintree.rb +36 -46
- data/lib/braintree/address.rb +14 -14
- data/lib/braintree/base_module.rb +3 -3
- data/lib/braintree/configuration.rb +16 -16
- data/lib/braintree/credit_card.rb +39 -30
- data/lib/braintree/credit_card_verification.rb +4 -3
- data/lib/braintree/customer.rb +22 -22
- data/lib/braintree/digest.rb +2 -8
- data/lib/braintree/error_codes.rb +16 -3
- data/lib/braintree/error_result.rb +5 -5
- data/lib/braintree/exceptions.rb +58 -0
- data/lib/braintree/http.rb +7 -7
- data/lib/braintree/paged_collection.rb +14 -14
- data/lib/braintree/ssl_expiration_check.rb +5 -1
- data/lib/braintree/subscription.rb +110 -0
- data/lib/braintree/successful_result.rb +3 -3
- data/lib/braintree/test/credit_card_numbers.rb +1 -1
- data/lib/braintree/test/transaction_amounts.rb +18 -0
- data/lib/braintree/transaction.rb +52 -25
- data/lib/braintree/transaction/address_details.rb +2 -2
- data/lib/braintree/transaction/credit_card_details.rb +12 -4
- data/lib/braintree/transaction/customer_details.rb +9 -1
- data/lib/braintree/transaction/status_details.rb +1 -1
- data/lib/braintree/transparent_redirect.rb +15 -15
- data/lib/braintree/util.rb +7 -7
- data/lib/braintree/validation_error.rb +1 -1
- data/lib/braintree/validation_error_collection.rb +6 -6
- data/lib/braintree/version.rb +3 -3
- data/lib/braintree/xml/generator.rb +2 -2
- data/lib/braintree/xml/libxml.rb +1 -1
- data/lib/braintree/xml/parser.rb +1 -1
- data/spec/integration/braintree/address_spec.rb +12 -12
- data/spec/integration/braintree/credit_card_spec.rb +189 -37
- data/spec/integration/braintree/customer_spec.rb +35 -35
- data/spec/integration/braintree/http_spec.rb +3 -3
- data/spec/integration/braintree/subscription_spec.rb +362 -0
- data/spec/integration/braintree/transaction_spec.rb +130 -58
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/spec_helper.rb +4 -4
- data/spec/unit/braintree/address_spec.rb +6 -6
- data/spec/unit/braintree/base_module_spec.rb +18 -0
- data/spec/unit/braintree/configuration_spec.rb +10 -10
- data/spec/unit/braintree/credit_card_spec.rb +15 -15
- data/spec/unit/braintree/credit_card_verification_spec.rb +4 -2
- data/spec/unit/braintree/customer_spec.rb +8 -8
- data/spec/unit/braintree/digest_spec.rb +4 -0
- data/spec/unit/braintree/http_spec.rb +2 -2
- data/spec/unit/braintree/paged_collection_spec.rb +12 -12
- data/spec/unit/braintree/ssl_expiration_check_spec.rb +18 -9
- data/spec/unit/braintree/transaction/credit_card_details_spec.rb +15 -0
- data/spec/unit/braintree/transaction/customer_details_spec.rb +19 -0
- data/spec/unit/braintree/transaction_spec.rb +14 -14
- data/spec/unit/braintree/transparent_redirect_spec.rb +11 -11
- data/spec/unit/braintree/util_spec.rb +8 -8
- data/spec/unit/braintree/validation_error_collection_spec.rb +6 -6
- data/spec/unit/braintree/validation_error_spec.rb +2 -2
- data/spec/unit/braintree/xml/libxml_spec.rb +5 -5
- data/spec/unit/braintree/xml_spec.rb +16 -16
- data/spec/unit/braintree_spec.rb +11 -0
- metadata +8 -2
@@ -38,6 +38,20 @@ module Braintree
|
|
38
38
|
_data(params)
|
39
39
|
end
|
40
40
|
|
41
|
+
def self.parse_and_validate_query_string(query_string) # :nodoc:
|
42
|
+
params = Util.symbolize_keys(Util.parse_query_string(query_string))
|
43
|
+
query_string_without_hash = query_string[/(.*)&hash=.*/, 1]
|
44
|
+
if _hash(query_string_without_hash) == params[:hash]
|
45
|
+
if params[:http_status] == '200'
|
46
|
+
params
|
47
|
+
else
|
48
|
+
Util.raise_exception_for_status_code(params[:http_status])
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise ForgedQueryString
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
41
55
|
# Returns the tr_data string for creating a transaction.
|
42
56
|
def self.transaction_data(params)
|
43
57
|
Util.verify_keys(TransactionSignature, params)
|
@@ -78,20 +92,6 @@ module Braintree
|
|
78
92
|
_data(params)
|
79
93
|
end
|
80
94
|
|
81
|
-
def self.parse_and_validate_query_string(query_string) # :nodoc:
|
82
|
-
params = Util.symbolize_keys(Util.parse_query_string(query_string))
|
83
|
-
query_string_without_hash = query_string[/(.*)&hash=.*/, 1]
|
84
|
-
if _hash(query_string_without_hash) == params[:hash]
|
85
|
-
if params[:http_status] == '200'
|
86
|
-
params
|
87
|
-
else
|
88
|
-
Util.raise_exception_for_status_code(params[:http_status])
|
89
|
-
end
|
90
|
-
else
|
91
|
-
raise ForgedQueryString
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
95
|
def self._data(params) # :nodoc:
|
96
96
|
raise ArgumentError, "expected params to contain :redirect_url" unless params[:redirect_url]
|
97
97
|
tr_data_segment = Util.hash_to_query_string(params.merge(
|
@@ -102,7 +102,7 @@ module Braintree
|
|
102
102
|
tr_data_hash = _hash(tr_data_segment)
|
103
103
|
"#{tr_data_hash}|#{tr_data_segment}"
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
def self._hash(string) # :nodoc:
|
107
107
|
::Braintree::Digest.hexdigest(string)
|
108
108
|
end
|
data/lib/braintree/util.rb
CHANGED
@@ -15,7 +15,7 @@ module Braintree
|
|
15
15
|
end
|
16
16
|
end.sort * '&'
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def self.parse_query_string(qs)
|
20
20
|
qs.split('&').inject({}) do |result, couplet|
|
21
21
|
pair = couplet.split('=')
|
@@ -23,7 +23,7 @@ module Braintree
|
|
23
23
|
result
|
24
24
|
end
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def self.url_encode(text)
|
28
28
|
CGI.escape text.to_s
|
29
29
|
end
|
@@ -37,10 +37,10 @@ module Braintree
|
|
37
37
|
elsif value.is_a?(Array) && value.all? { |v| v.is_a?(Hash) }
|
38
38
|
value.each { |v| symbolize_keys(v) }
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
41
41
|
hash
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def self.raise_exception_for_status_code(status_code)
|
45
45
|
case status_code.to_i
|
46
46
|
when 401
|
@@ -57,7 +57,7 @@ module Braintree
|
|
57
57
|
raise UnexpectedError, "Unexpected HTTP_RESPONSE #{status_code.to_i}"
|
58
58
|
end
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def self.verify_keys(valid_keys, hash)
|
62
62
|
flattened_valid_keys = _flatten_valid_keys(valid_keys)
|
63
63
|
invalid_keys = _flatten_hash_keys(hash) - flattened_valid_keys
|
@@ -67,7 +67,7 @@ module Braintree
|
|
67
67
|
raise ArgumentError, "invalid keys: #{sorted}"
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def self._flatten_valid_keys(valid_keys, namespace = nil)
|
72
72
|
valid_keys.inject([]) do |result, key|
|
73
73
|
if key.is_a?(Hash)
|
@@ -85,7 +85,7 @@ module Braintree
|
|
85
85
|
result
|
86
86
|
end.sort
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
def self._flatten_hash_keys(hash, namespace = nil)
|
90
90
|
hash.inject([]) do |result, (key, value)|
|
91
91
|
full_key = (namespace ? "#{namespace}[#{key}]" : key.to_s)
|
@@ -20,7 +20,7 @@ module Braintree
|
|
20
20
|
# #=> [#<Braintree::ValidationError (91803) Country name is not an accepted country.>]
|
21
21
|
class ValidationErrorCollection
|
22
22
|
include Enumerable
|
23
|
-
|
23
|
+
|
24
24
|
def initialize(data) # :nodoc:
|
25
25
|
@errors = data[:errors].map { |hash| Braintree::ValidationError.new(hash) }
|
26
26
|
@nested = {}
|
@@ -29,7 +29,7 @@ module Braintree
|
|
29
29
|
@nested[key] = ValidationErrorCollection.new(data[key])
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# Accesses the error at the given index.
|
34
34
|
def [](index)
|
35
35
|
@errors[index]
|
@@ -38,7 +38,7 @@ module Braintree
|
|
38
38
|
def deep_size # :nodoc:
|
39
39
|
size + @nested.values.inject(0) { |count, error_collection| count + error_collection.deep_size }
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
# Iterates over errors at the current level. Nested errors will not be yielded.
|
43
43
|
def each(&block)
|
44
44
|
@errors.each(&block)
|
@@ -58,11 +58,11 @@ module Braintree
|
|
58
58
|
def on(attribute)
|
59
59
|
@errors.select { |error| error.attribute == attribute.to_s }
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
# The number of errors at this level. This does not include nested errors.
|
63
63
|
def size
|
64
64
|
@errors.size
|
65
|
-
end
|
65
|
+
end
|
66
66
|
|
67
67
|
def _inner_inspect(scope = []) # :nodoc:
|
68
68
|
all = []
|
@@ -75,6 +75,6 @@ module Braintree
|
|
75
75
|
end
|
76
76
|
all.join(", ")
|
77
77
|
end
|
78
|
-
end
|
78
|
+
end
|
79
79
|
end
|
80
80
|
|
data/lib/braintree/version.rb
CHANGED
@@ -15,7 +15,7 @@ module Braintree
|
|
15
15
|
"symbol" => Proc.new { |symbol| symbol.to_s },
|
16
16
|
"datetime" => Proc.new { |time| time.xmlschema },
|
17
17
|
}
|
18
|
-
|
18
|
+
|
19
19
|
def self.hash_to_xml(hash)
|
20
20
|
root, contents = hash.keys[0], hash.values[0]
|
21
21
|
|
@@ -60,7 +60,7 @@ module Braintree
|
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def self._array_to_xml(array, options = {})
|
65
65
|
raise "expected all elements to be hashes" unless array.all? { |e| e.is_a?(Hash) }
|
66
66
|
raise "expected options[:root]" unless options[:root]
|
data/lib/braintree/xml/libxml.rb
CHANGED
data/lib/braintree/xml/parser.rb
CHANGED
@@ -48,7 +48,7 @@ module Braintree
|
|
48
48
|
""
|
49
49
|
elsif value.nil? || value['nil'] == 'true'
|
50
50
|
nil
|
51
|
-
# If the type is the only element which makes it then
|
51
|
+
# If the type is the only element which makes it then
|
52
52
|
# this still makes the value nil, except if type is
|
53
53
|
# a XML node(where type['value'] is a Hash)
|
54
54
|
elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
|
@@ -28,7 +28,7 @@ describe Braintree::Address do
|
|
28
28
|
result.address.postal_code.should == "60622"
|
29
29
|
result.address.country_name.should == "United States of America"
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
it "returns an error response if invalid" do
|
33
33
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
34
34
|
result = Braintree::Address.create(
|
@@ -72,7 +72,7 @@ describe Braintree::Address do
|
|
72
72
|
address.postal_code.should == "60623"
|
73
73
|
address.country_name.should == "United States of America"
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
it "raises a ValidationsFailed if invalid" do
|
77
77
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
78
78
|
expect do
|
@@ -83,7 +83,7 @@ describe Braintree::Address do
|
|
83
83
|
end.to raise_error(Braintree::ValidationsFailed)
|
84
84
|
end
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
describe "self.delete" do
|
88
88
|
it "deletes the address given a customer id and an address id" do
|
89
89
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
@@ -103,7 +103,7 @@ describe Braintree::Address do
|
|
103
103
|
end.to raise_error(Braintree::NotFoundError)
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
describe "self.find" do
|
108
108
|
it "finds the address given a customer and an address id" do
|
109
109
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
@@ -116,7 +116,7 @@ describe Braintree::Address do
|
|
116
116
|
address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
|
117
117
|
Braintree::Address.find(customer.id, address.id).should == address
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
it "raises a NotFoundError if it cannot be found because of customer id" do
|
121
121
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
122
122
|
address = Braintree::Address.create!(:customer_id => customer.id, :street_address => "123 E Main St")
|
@@ -137,7 +137,7 @@ describe Braintree::Address do
|
|
137
137
|
"address for customer \"#{customer.id}\" with id \"invalid\" not found")
|
138
138
|
end
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
describe "self.update" do
|
142
142
|
it "raises NotFoundError if the address can't be found" do
|
143
143
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
@@ -176,7 +176,7 @@ describe Braintree::Address do
|
|
176
176
|
result.address.postal_code.should == "60621"
|
177
177
|
result.address.country_name.should == "United States of America"
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
it "returns an error response if invalid" do
|
181
181
|
customer = Braintree::Customer.create!(:last_name => "Miller")
|
182
182
|
address = Braintree::Address.create!(
|
@@ -232,7 +232,7 @@ describe Braintree::Address do
|
|
232
232
|
updated_address.postal_code.should == "60621"
|
233
233
|
updated_address.country_name.should == "United States of America"
|
234
234
|
end
|
235
|
-
|
235
|
+
|
236
236
|
it "raises a ValidationsFailed invalid" do
|
237
237
|
customer = Braintree::Customer.create!(:last_name => "Miller")
|
238
238
|
address = Braintree::Address.create!(
|
@@ -250,7 +250,7 @@ describe Braintree::Address do
|
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
-
|
253
|
+
|
254
254
|
describe "delete" do
|
255
255
|
it "deletes the address" do
|
256
256
|
customer = Braintree::Customer.create!(:last_name => "Wilson")
|
@@ -261,7 +261,7 @@ describe Braintree::Address do
|
|
261
261
|
end.to raise_error(Braintree::NotFoundError)
|
262
262
|
end
|
263
263
|
end
|
264
|
-
|
264
|
+
|
265
265
|
describe "update" do
|
266
266
|
it "returns a success response and updates the address if valid" do
|
267
267
|
customer = Braintree::Customer.create!(:last_name => "Miller")
|
@@ -291,7 +291,7 @@ describe Braintree::Address do
|
|
291
291
|
address.postal_code.should == "60621"
|
292
292
|
address.country_name.should == "United States of America"
|
293
293
|
end
|
294
|
-
|
294
|
+
|
295
295
|
it "returns an error response if invalid" do
|
296
296
|
customer = Braintree::Customer.create!(:last_name => "Miller")
|
297
297
|
address = Braintree::Address.create!(
|
@@ -334,7 +334,7 @@ describe Braintree::Address do
|
|
334
334
|
address.postal_code.should == "60621"
|
335
335
|
address.country_name.should == "United States of America"
|
336
336
|
end
|
337
|
-
|
337
|
+
|
338
338
|
it "raises a ValidationsFailed invalid" do
|
339
339
|
customer = Braintree::Customer.create!(:last_name => "Miller")
|
340
340
|
address = Braintree::Address.create!(
|
@@ -53,6 +53,8 @@ describe Braintree::CreditCard do
|
|
53
53
|
)
|
54
54
|
result.success?.should == false
|
55
55
|
result.credit_card_verification.status.should == "processor_declined"
|
56
|
+
result.credit_card_verification.processor_response_code.should == "2000"
|
57
|
+
result.credit_card_verification.processor_response_text.should == "Do Not Honor"
|
56
58
|
result.credit_card_verification.cvv_response_code.should == "I"
|
57
59
|
result.credit_card_verification.avs_error_response_code.should == nil
|
58
60
|
result.credit_card_verification.avs_postal_code_response_code.should == "I"
|
@@ -69,7 +71,7 @@ describe Braintree::CreditCard do
|
|
69
71
|
)
|
70
72
|
result.success?.should == true
|
71
73
|
end
|
72
|
-
|
74
|
+
|
73
75
|
it "adds credit card with billing address to customer" do
|
74
76
|
customer = Braintree::Customer.create!
|
75
77
|
result = Braintree::CreditCard.create(
|
@@ -88,7 +90,7 @@ describe Braintree::CreditCard do
|
|
88
90
|
credit_card.bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
|
89
91
|
credit_card.billing_address.street_address.should == "123 Abc Way"
|
90
92
|
end
|
91
|
-
|
93
|
+
|
92
94
|
it "returns an error response if unsuccessful" do
|
93
95
|
customer = Braintree::Customer.create!
|
94
96
|
result = Braintree::CreditCard.create(
|
@@ -127,7 +129,7 @@ describe Braintree::CreditCard do
|
|
127
129
|
end.to raise_error(Braintree::ValidationsFailed)
|
128
130
|
end
|
129
131
|
end
|
130
|
-
|
132
|
+
|
131
133
|
describe "self.credit" do
|
132
134
|
it "creates a credit transaction using the payment method token, returning a result object" do
|
133
135
|
customer = Braintree::Customer.create!(
|
@@ -141,7 +143,7 @@ describe Braintree::CreditCard do
|
|
141
143
|
:amount => "100.00"
|
142
144
|
)
|
143
145
|
result.success?.should == true
|
144
|
-
result.transaction.amount.should == "100.00"
|
146
|
+
result.transaction.amount.should == BigDecimal.new("100.00")
|
145
147
|
result.transaction.type.should == "credit"
|
146
148
|
result.transaction.customer_details.id.should == customer.id
|
147
149
|
result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -150,7 +152,7 @@ describe Braintree::CreditCard do
|
|
150
152
|
result.transaction.credit_card_details.expiration_date.should == "05/2010"
|
151
153
|
end
|
152
154
|
end
|
153
|
-
|
155
|
+
|
154
156
|
describe "self.credit!" do
|
155
157
|
it "creates a credit transaction using the payment method token, returning the transaction" do
|
156
158
|
customer = Braintree::Customer.create!(
|
@@ -163,7 +165,7 @@ describe Braintree::CreditCard do
|
|
163
165
|
customer.credit_cards[0].token,
|
164
166
|
:amount => "100.00"
|
165
167
|
)
|
166
|
-
transaction.amount.should == "100.00"
|
168
|
+
transaction.amount.should == BigDecimal.new("100.00")
|
167
169
|
transaction.type.should == "credit"
|
168
170
|
transaction.customer_details.id.should == customer.id
|
169
171
|
transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -202,7 +204,7 @@ describe Braintree::CreditCard do
|
|
202
204
|
credit_card.expiration_date.should == "05/2012"
|
203
205
|
credit_card.customer_id.should == customer.id
|
204
206
|
end
|
205
|
-
|
207
|
+
|
206
208
|
it "returns xml with nested errors if validation errors" do
|
207
209
|
customer = Braintree::Customer.create.customer
|
208
210
|
params = {
|
@@ -218,7 +220,7 @@ describe Braintree::CreditCard do
|
|
218
220
|
}
|
219
221
|
}
|
220
222
|
query_string_response = create_credit_card_via_tr(params, tr_data_params)
|
221
|
-
result = Braintree::CreditCard.create_from_transparent_redirect(query_string_response)
|
223
|
+
result = Braintree::CreditCard.create_from_transparent_redirect(query_string_response)
|
222
224
|
result.success?.should == false
|
223
225
|
result.params[:customer_id] == customer.id
|
224
226
|
result.params[:credit_card]["cardholder_name"] == customer.id
|
@@ -227,6 +229,156 @@ describe Braintree::CreditCard do
|
|
227
229
|
end
|
228
230
|
end
|
229
231
|
|
232
|
+
describe "self.update" do
|
233
|
+
it "updates the credit card" do
|
234
|
+
customer = Braintree::Customer.create!
|
235
|
+
credit_card = Braintree::CreditCard.create!(
|
236
|
+
:cardholder_name => "Original Holder",
|
237
|
+
:customer_id => customer.id,
|
238
|
+
:cvv => "123",
|
239
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
240
|
+
:expiration_date => "05/2012"
|
241
|
+
)
|
242
|
+
update_result = Braintree::CreditCard.update(credit_card.token,
|
243
|
+
:cardholder_name => "New Holder",
|
244
|
+
:cvv => "456",
|
245
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
246
|
+
:expiration_date => "06/2013"
|
247
|
+
)
|
248
|
+
update_result.success?.should == true
|
249
|
+
update_result.credit_card.should == credit_card
|
250
|
+
updated_credit_card = update_result.credit_card
|
251
|
+
updated_credit_card.bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
|
252
|
+
updated_credit_card.last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
|
253
|
+
updated_credit_card.expiration_date.should == "06/2013"
|
254
|
+
updated_credit_card.cardholder_name.should == "New Holder"
|
255
|
+
end
|
256
|
+
|
257
|
+
it "verifies the update if options[verify_card]=true" do
|
258
|
+
customer = Braintree::Customer.create!
|
259
|
+
credit_card = Braintree::CreditCard.create!(
|
260
|
+
:cardholder_name => "Original Holder",
|
261
|
+
:customer_id => customer.id,
|
262
|
+
:cvv => "123",
|
263
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
264
|
+
:expiration_date => "05/2012"
|
265
|
+
)
|
266
|
+
update_result = Braintree::CreditCard.update(credit_card.token,
|
267
|
+
:cardholder_name => "New Holder",
|
268
|
+
:cvv => "456",
|
269
|
+
:number => Braintree::Test::CreditCardNumbers::FailsSandboxVerification::MasterCard,
|
270
|
+
:expiration_date => "06/2013",
|
271
|
+
:options => {:verify_card => true}
|
272
|
+
)
|
273
|
+
update_result.success?.should == false
|
274
|
+
update_result.credit_card_verification.status.should == "processor_declined"
|
275
|
+
end
|
276
|
+
|
277
|
+
it "can update the billing address" do
|
278
|
+
customer = Braintree::Customer.create!
|
279
|
+
credit_card = Braintree::CreditCard.create!(
|
280
|
+
:cardholder_name => "Original Holder",
|
281
|
+
:customer_id => customer.id,
|
282
|
+
:cvv => "123",
|
283
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
284
|
+
:expiration_date => "05/2012",
|
285
|
+
:billing_address => {
|
286
|
+
:first_name => "Old First Name",
|
287
|
+
:last_name => "Old Last Name",
|
288
|
+
:company => "Old Company",
|
289
|
+
:street_address => "123 Old St",
|
290
|
+
:extended_address => "Apt Old",
|
291
|
+
:locality => "Old City",
|
292
|
+
:region => "Old State",
|
293
|
+
:postal_code => "12345",
|
294
|
+
:country_name => "Canada"
|
295
|
+
}
|
296
|
+
)
|
297
|
+
result = Braintree::CreditCard.update(credit_card.token,
|
298
|
+
:options => {:verify_card => false},
|
299
|
+
:billing_address => {
|
300
|
+
:first_name => "New First Name",
|
301
|
+
:last_name => "New Last Name",
|
302
|
+
:company => "New Company",
|
303
|
+
:street_address => "123 New St",
|
304
|
+
:extended_address => "Apt New",
|
305
|
+
:locality => "New City",
|
306
|
+
:region => "New State",
|
307
|
+
:postal_code => "56789",
|
308
|
+
:country_name => "United States of America"
|
309
|
+
}
|
310
|
+
)
|
311
|
+
result.success?.should == true
|
312
|
+
address = result.credit_card.billing_address
|
313
|
+
address.first_name.should == "New First Name"
|
314
|
+
address.last_name.should == "New Last Name"
|
315
|
+
address.company.should == "New Company"
|
316
|
+
address.street_address.should == "123 New St"
|
317
|
+
address.extended_address.should == "Apt New"
|
318
|
+
address.locality.should == "New City"
|
319
|
+
address.region.should == "New State"
|
320
|
+
address.postal_code.should == "56789"
|
321
|
+
address.country_name.should == "United States of America"
|
322
|
+
end
|
323
|
+
|
324
|
+
it "returns an error response if invalid" do
|
325
|
+
customer = Braintree::Customer.create!
|
326
|
+
credit_card = Braintree::CreditCard.create!(
|
327
|
+
:cardholder_name => "Original Holder",
|
328
|
+
:customer_id => customer.id,
|
329
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
330
|
+
:expiration_date => "05/2012"
|
331
|
+
)
|
332
|
+
update_result = Braintree::CreditCard.update(credit_card.token,
|
333
|
+
:cardholder_name => "New Holder",
|
334
|
+
:number => "invalid",
|
335
|
+
:expiration_date => "05/2014"
|
336
|
+
)
|
337
|
+
update_result.success?.should == false
|
338
|
+
update_result.errors.for(:credit_card).on(:number)[0].message.should == "Credit card number must be 12-19 digits."
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe "self.update!" do
|
343
|
+
it "updates the credit card and returns true if valid" do
|
344
|
+
customer = Braintree::Customer.create!
|
345
|
+
credit_card = Braintree::CreditCard.create!(
|
346
|
+
:cardholder_name => "Original Holder",
|
347
|
+
:customer_id => customer.id,
|
348
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
349
|
+
:expiration_date => "05/2012"
|
350
|
+
)
|
351
|
+
updated_credit_card = Braintree::CreditCard.update!(credit_card.token,
|
352
|
+
:cardholder_name => "New Holder",
|
353
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
354
|
+
:expiration_date => "06/2013"
|
355
|
+
)
|
356
|
+
updated_credit_card.token.should == credit_card.token
|
357
|
+
updated_credit_card.bin.should == Braintree::Test::CreditCardNumbers::MasterCard[0, 6]
|
358
|
+
updated_credit_card.last_4.should == Braintree::Test::CreditCardNumbers::MasterCard[-4..-1]
|
359
|
+
updated_credit_card.expiration_date.should == "06/2013"
|
360
|
+
updated_credit_card.cardholder_name.should == "New Holder"
|
361
|
+
updated_credit_card.updated_at.between?(Time.now - 5, Time.now).should == true
|
362
|
+
end
|
363
|
+
|
364
|
+
it "raises a ValidationsFailed if invalid" do
|
365
|
+
customer = Braintree::Customer.create!
|
366
|
+
credit_card = Braintree::CreditCard.create!(
|
367
|
+
:cardholder_name => "Original Holder",
|
368
|
+
:customer_id => customer.id,
|
369
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
370
|
+
:expiration_date => "05/2012"
|
371
|
+
)
|
372
|
+
expect do
|
373
|
+
Braintree::CreditCard.update!(credit_card.token,
|
374
|
+
:cardholder_name => "New Holder",
|
375
|
+
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
376
|
+
:expiration_date => "invalid/date"
|
377
|
+
)
|
378
|
+
end.to raise_error(Braintree::ValidationsFailed)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
230
382
|
describe "self.update_from_transparent_redirect" do
|
231
383
|
it "updates the credit card" do
|
232
384
|
old_token = "token#{rand(1_000_000)}"
|
@@ -276,7 +428,7 @@ describe Braintree::CreditCard do
|
|
276
428
|
:amount => "100.00"
|
277
429
|
)
|
278
430
|
result.success?.should == true
|
279
|
-
result.transaction.amount.should == "100.00"
|
431
|
+
result.transaction.amount.should == BigDecimal.new("100.00")
|
280
432
|
result.transaction.type.should == "credit"
|
281
433
|
result.transaction.customer_details.id.should == customer.id
|
282
434
|
result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -295,7 +447,7 @@ describe Braintree::CreditCard do
|
|
295
447
|
}
|
296
448
|
)
|
297
449
|
transaction = customer.credit_cards[0].credit!(:amount => "100.00")
|
298
|
-
transaction.amount.should == "100.00"
|
450
|
+
transaction.amount.should == BigDecimal.new("100.00")
|
299
451
|
transaction.type.should == "credit"
|
300
452
|
transaction.customer_details.id.should == customer.id
|
301
453
|
transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -303,7 +455,7 @@ describe Braintree::CreditCard do
|
|
303
455
|
transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
|
304
456
|
transaction.credit_card_details.expiration_date.should == "05/2010"
|
305
457
|
end
|
306
|
-
|
458
|
+
|
307
459
|
it "raises a ValidationsFailed if invalid" do
|
308
460
|
customer = Braintree::Customer.create!(
|
309
461
|
:credit_card => {
|
@@ -316,16 +468,16 @@ describe Braintree::CreditCard do
|
|
316
468
|
end.to raise_error(Braintree::ValidationsFailed)
|
317
469
|
end
|
318
470
|
end
|
319
|
-
|
471
|
+
|
320
472
|
describe "delete" do
|
321
473
|
it "deletes the credit card" do
|
322
474
|
customer = Braintree::Customer.create.customer
|
323
475
|
result = Braintree::CreditCard.create(
|
324
476
|
:customer_id => customer.id,
|
325
477
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
326
|
-
:expiration_date => "05/2012"
|
478
|
+
:expiration_date => "05/2012"
|
327
479
|
)
|
328
|
-
|
480
|
+
|
329
481
|
result.success?.should == true
|
330
482
|
credit_card = result.credit_card
|
331
483
|
credit_card.delete.should == true
|
@@ -334,7 +486,7 @@ describe Braintree::CreditCard do
|
|
334
486
|
end.to raise_error(Braintree::NotFoundError)
|
335
487
|
end
|
336
488
|
end
|
337
|
-
|
489
|
+
|
338
490
|
describe "self.expired" do
|
339
491
|
it "finds expired payment methods, paginated" do
|
340
492
|
first_page = Braintree::CreditCard.expired
|
@@ -353,7 +505,7 @@ describe Braintree::CreditCard do
|
|
353
505
|
# second_page.all? { |pm| pm.expired?.should == true }
|
354
506
|
end
|
355
507
|
end
|
356
|
-
|
508
|
+
|
357
509
|
describe "self.expiring_between" do
|
358
510
|
it "finds payment methods expiring between the given dates" do
|
359
511
|
next_year = Time.now.year + 1
|
@@ -382,7 +534,7 @@ describe Braintree::CreditCard do
|
|
382
534
|
result = Braintree::CreditCard.create(
|
383
535
|
:customer_id => customer.id,
|
384
536
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
385
|
-
:expiration_date => "05/2012"
|
537
|
+
:expiration_date => "05/2012"
|
386
538
|
)
|
387
539
|
result.success?.should == true
|
388
540
|
credit_card = Braintree::CreditCard.find(result.credit_card.token)
|
@@ -391,14 +543,14 @@ describe Braintree::CreditCard do
|
|
391
543
|
credit_card.token.should == result.credit_card.token
|
392
544
|
credit_card.expiration_date.should == "05/2012"
|
393
545
|
end
|
394
|
-
|
546
|
+
|
395
547
|
it "raises a NotFoundError exception if payment method cannot be found" do
|
396
548
|
expect do
|
397
549
|
Braintree::CreditCard.find("invalid-token")
|
398
550
|
end.to raise_error(Braintree::NotFoundError, 'payment method with token "invalid-token" not found')
|
399
551
|
end
|
400
552
|
end
|
401
|
-
|
553
|
+
|
402
554
|
describe "self.sale" do
|
403
555
|
it "creates a sale transaction using the credit card, returning a result object" do
|
404
556
|
customer = Braintree::Customer.create!(
|
@@ -410,7 +562,7 @@ describe Braintree::CreditCard do
|
|
410
562
|
result = Braintree::CreditCard.sale(customer.credit_cards[0].token, :amount => "100.00")
|
411
563
|
|
412
564
|
result.success?.should == true
|
413
|
-
result.transaction.amount.should == "100.00"
|
565
|
+
result.transaction.amount.should == BigDecimal.new("100.00")
|
414
566
|
result.transaction.type.should == "sale"
|
415
567
|
result.transaction.customer_details.id.should == customer.id
|
416
568
|
result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -429,7 +581,7 @@ describe Braintree::CreditCard do
|
|
429
581
|
}
|
430
582
|
)
|
431
583
|
transaction = Braintree::CreditCard.sale!(customer.credit_cards[0].token, :amount => "100.00")
|
432
|
-
transaction.amount.should == "100.00"
|
584
|
+
transaction.amount.should == BigDecimal.new("100.00")
|
433
585
|
transaction.type.should == "sale"
|
434
586
|
transaction.customer_details.id.should == customer.id
|
435
587
|
transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -438,7 +590,7 @@ describe Braintree::CreditCard do
|
|
438
590
|
transaction.credit_card_details.expiration_date.should == "05/2010"
|
439
591
|
end
|
440
592
|
end
|
441
|
-
|
593
|
+
|
442
594
|
describe "sale" do
|
443
595
|
it "creates a sale transaction using the credit card, returning a result object" do
|
444
596
|
customer = Braintree::Customer.create!(
|
@@ -451,7 +603,7 @@ describe Braintree::CreditCard do
|
|
451
603
|
:amount => "100.00"
|
452
604
|
)
|
453
605
|
result.success?.should == true
|
454
|
-
result.transaction.amount.should == "100.00"
|
606
|
+
result.transaction.amount.should == BigDecimal.new("100.00")
|
455
607
|
result.transaction.type.should == "sale"
|
456
608
|
result.transaction.customer_details.id.should == customer.id
|
457
609
|
result.transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -470,7 +622,7 @@ describe Braintree::CreditCard do
|
|
470
622
|
}
|
471
623
|
)
|
472
624
|
transaction = customer.credit_cards[0].sale!(:amount => "100.00")
|
473
|
-
transaction.amount.should == "100.00"
|
625
|
+
transaction.amount.should == BigDecimal.new("100.00")
|
474
626
|
transaction.type.should == "sale"
|
475
627
|
transaction.customer_details.id.should == customer.id
|
476
628
|
transaction.credit_card_details.token.should == customer.credit_cards[0].token
|
@@ -478,7 +630,7 @@ describe Braintree::CreditCard do
|
|
478
630
|
transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
|
479
631
|
transaction.credit_card_details.expiration_date.should == "05/2010"
|
480
632
|
end
|
481
|
-
|
633
|
+
|
482
634
|
it "raises a ValidationsFailed if invalid" do
|
483
635
|
customer = Braintree::Customer.create!(
|
484
636
|
:credit_card => {
|
@@ -491,7 +643,7 @@ describe Braintree::CreditCard do
|
|
491
643
|
end.to raise_error(Braintree::ValidationsFailed)
|
492
644
|
end
|
493
645
|
end
|
494
|
-
|
646
|
+
|
495
647
|
describe "update" do
|
496
648
|
it "updates the credit card" do
|
497
649
|
customer = Braintree::Customer.create!
|
@@ -500,7 +652,7 @@ describe Braintree::CreditCard do
|
|
500
652
|
:customer_id => customer.id,
|
501
653
|
:cvv => "123",
|
502
654
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
503
|
-
:expiration_date => "05/2012"
|
655
|
+
:expiration_date => "05/2012"
|
504
656
|
)
|
505
657
|
update_result = credit_card.update(
|
506
658
|
:cardholder_name => "New Holder",
|
@@ -524,7 +676,7 @@ describe Braintree::CreditCard do
|
|
524
676
|
:customer_id => customer.id,
|
525
677
|
:cvv => "123",
|
526
678
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
527
|
-
:expiration_date => "05/2012"
|
679
|
+
:expiration_date => "05/2012"
|
528
680
|
)
|
529
681
|
update_result = credit_card.update(
|
530
682
|
:cardholder_name => "New Holder",
|
@@ -555,7 +707,7 @@ describe Braintree::CreditCard do
|
|
555
707
|
:region => "Old State",
|
556
708
|
:postal_code => "12345",
|
557
709
|
:country_name => "Canada"
|
558
|
-
}
|
710
|
+
}
|
559
711
|
)
|
560
712
|
result = credit_card.update(
|
561
713
|
:options => {:verify_card => false},
|
@@ -584,14 +736,14 @@ describe Braintree::CreditCard do
|
|
584
736
|
address.postal_code.should == "56789"
|
585
737
|
address.country_name.should == "United States of America"
|
586
738
|
end
|
587
|
-
|
739
|
+
|
588
740
|
it "returns an error response if invalid" do
|
589
741
|
customer = Braintree::Customer.create!
|
590
742
|
credit_card = Braintree::CreditCard.create!(
|
591
743
|
:cardholder_name => "Original Holder",
|
592
744
|
:customer_id => customer.id,
|
593
745
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
594
|
-
:expiration_date => "05/2012"
|
746
|
+
:expiration_date => "05/2012"
|
595
747
|
)
|
596
748
|
update_result = credit_card.update(
|
597
749
|
:cardholder_name => "New Holder",
|
@@ -610,7 +762,7 @@ describe Braintree::CreditCard do
|
|
610
762
|
:cardholder_name => "Original Holder",
|
611
763
|
:customer_id => customer.id,
|
612
764
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
613
|
-
:expiration_date => "05/2012"
|
765
|
+
:expiration_date => "05/2012"
|
614
766
|
)
|
615
767
|
credit_card.update!(
|
616
768
|
:cardholder_name => "New Holder",
|
@@ -623,14 +775,14 @@ describe Braintree::CreditCard do
|
|
623
775
|
credit_card.cardholder_name.should == "New Holder"
|
624
776
|
credit_card.updated_at.between?(Time.now - 5, Time.now).should == true
|
625
777
|
end
|
626
|
-
|
778
|
+
|
627
779
|
it "raises a ValidationsFailed if invalid" do
|
628
780
|
customer = Braintree::Customer.create!
|
629
781
|
credit_card = Braintree::CreditCard.create!(
|
630
782
|
:cardholder_name => "Original Holder",
|
631
783
|
:customer_id => customer.id,
|
632
784
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
633
|
-
:expiration_date => "05/2012"
|
785
|
+
:expiration_date => "05/2012"
|
634
786
|
)
|
635
787
|
expect do
|
636
788
|
credit_card.update!(
|
@@ -641,7 +793,7 @@ describe Braintree::CreditCard do
|
|
641
793
|
end.to raise_error(Braintree::ValidationsFailed)
|
642
794
|
end
|
643
795
|
end
|
644
|
-
|
796
|
+
|
645
797
|
def create_credit_card_via_tr(regular_params, tr_params = {})
|
646
798
|
response = nil
|
647
799
|
Net::HTTP.start("localhost", Braintree::Configuration.port) do |http|
|
@@ -652,7 +804,7 @@ describe Braintree::CreditCard do
|
|
652
804
|
response = http.request(request)
|
653
805
|
end
|
654
806
|
if response.code.to_i == 303
|
655
|
-
query_string = response["Location"].split("?", 2).last
|
807
|
+
query_string = response["Location"].split("?", 2).last
|
656
808
|
else
|
657
809
|
raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
|
658
810
|
end
|
@@ -668,7 +820,7 @@ describe Braintree::CreditCard do
|
|
668
820
|
response = http.request(request)
|
669
821
|
end
|
670
822
|
if response.code.to_i == 303
|
671
|
-
query_string = response["Location"].split("?", 2).last
|
823
|
+
query_string = response["Location"].split("?", 2).last
|
672
824
|
else
|
673
825
|
raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
|
674
826
|
end
|