braintree 2.22.0 → 2.23.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/lib/braintree.rb CHANGED
@@ -54,11 +54,13 @@ require "braintree/subscription_gateway"
54
54
  require "braintree/subscription_search"
55
55
  require "braintree/successful_result"
56
56
  require "braintree/test/credit_card"
57
+ require "braintree/test/venmo_sdk"
57
58
  require "braintree/test/transaction_amounts"
58
59
  require "braintree/transaction"
59
60
  require "braintree/transaction/address_details"
60
61
  require "braintree/transaction/credit_card_details"
61
62
  require "braintree/transaction/customer_details"
63
+ require "braintree/transaction/disbursement_details"
62
64
  require "braintree/transaction/subscription_details"
63
65
  require "braintree/transaction_gateway"
64
66
  require "braintree/transaction_search"
@@ -132,5 +132,9 @@ module Braintree
132
132
  logger.level = Logger::INFO
133
133
  logger
134
134
  end
135
+
136
+ def inspect
137
+ super.gsub(/@private_key=\".*\"/, '@private_key="[FILTERED]"')
138
+ end
135
139
  end
136
140
  end
@@ -37,7 +37,8 @@ module Braintree
37
37
 
38
38
  attr_reader :billing_address, :bin, :card_type, :cardholder_name, :commercial, :country_of_issuance,
39
39
  :created_at, :customer_id, :debit, :durbin_regulated, :expiration_month, :expiration_year, :healthcare,
40
- :issuing_bank, :last_4, :payroll, :prepaid, :subscriptions, :token, :unique_number_identifier, :updated_at
40
+ :issuing_bank, :last_4, :payroll, :prepaid, :subscriptions, :token, :unique_number_identifier, :updated_at,
41
+ :image_url
41
42
 
42
43
  # See http://www.braintreepayments.com/docs/ruby/credit_cards/create
43
44
  def self.create(attributes)
@@ -224,6 +225,11 @@ module Braintree
224
225
  return_object_or_raise(:credit_card) { update(attributes) }
225
226
  end
226
227
 
228
+ # Returns true if the card is associated with Venmo SDK
229
+ def venmo_sdk?
230
+ @venmo_sdk
231
+ end
232
+
227
233
  # Returns true if +other+ is a +CreditCard+ with the same token.
228
234
  def ==(other)
229
235
  return false unless other.is_a?(CreditCard)
@@ -238,7 +244,7 @@ module Braintree
238
244
  [
239
245
  :billing_address, :bin, :card_type, :cardholder_name, :created_at, :customer_id, :expiration_month,
240
246
  :expiration_year, :last_4, :token, :updated_at, :prepaid, :payroll, :commercial, :debit, :durbin_regulated,
241
- :healthcare, :country_of_issuance, :issuing_bank
247
+ :healthcare, :country_of_issuance, :issuing_bank, :image_url
242
248
  ]
243
249
  end
244
250
 
@@ -121,6 +121,11 @@ module Braintree
121
121
  return_object_or_raise(:transaction) { credit(transaction_attributes) }
122
122
  end
123
123
 
124
+ # Returns the default credit card of the customer
125
+ def default_credit_card
126
+ @credit_cards.find {|credit_card| credit_card.default? }
127
+ end
128
+
124
129
  # See http://www.braintreepayments.com/docs/ruby/customers/delete
125
130
  def delete
126
131
  @gateway.customer.delete(id)
@@ -6,20 +6,28 @@ module Braintree
6
6
  # See http://www.braintreepayments.com/docs/ruby/addresses/validations
7
7
  module Address
8
8
  CannotBeBlank = "81801"
9
+ CompanyIsInvalid = "91821"
9
10
  CompanyIsTooLong = "81802"
10
11
  CountryCodeAlpha2IsNotAccepted = "91814"
11
12
  CountryCodeAlpha3IsNotAccepted = "91816"
12
13
  CountryCodeNumericIsNotAccepted = "91817"
13
14
  CountryNameIsNotAccepted = "91803"
15
+ ExtendedAddressIsInvalid = "91823"
14
16
  ExtendedAddressIsTooLong = "81804"
17
+ FirstNameIsInvalid = "91819"
15
18
  FirstNameIsTooLong = "81805"
16
19
  InconsistentCountry = "91815"
20
+ LastNameIsInvalid = "91820"
17
21
  LastNameIsTooLong = "81806"
22
+ LocalityIsInvalid = "91824"
18
23
  LocalityIsTooLong = "81807"
19
24
  PostalCodeInvalidCharacters = "81813"
25
+ PostalCodeIsInvalid = "91826"
20
26
  PostalCodeIsRequired = "81808"
21
27
  PostalCodeIsTooLong = "81809"
28
+ RegionIsInvalid = "91825"
22
29
  RegionIsTooLong = "81810"
30
+ StreetAddressIsInvalid = "91822"
23
31
  StreetAddressIsRequired = "81811"
24
32
  StreetAddressIsTooLong = "81812"
25
33
  TooManyAddressesPerCustomer = "91818"
@@ -43,18 +51,24 @@ module Braintree
43
51
  ExpirationDateYearIsInvalid = "81711"
44
52
  ExpirationMonthIsInvalid = "81712"
45
53
  ExpirationYearIsInvalid = "81713"
54
+ InvalidVenmoSDKPaymentMethodCode = "91727"
46
55
  NumberHasInvalidLength = "81716"
56
+ NumberLengthIsInvalid = "81716"
47
57
  NumberIsInvalid = "81715"
48
58
  NumberIsRequired = "81714"
49
59
  NumberMustBeTestNumber = "81717"
60
+ PaymentMethodConflict = "81725"
50
61
  TokenInvalid = "91718"
62
+ TokenFormatIsInvalid = "91718"
51
63
  TokenIsInUse = "91719"
52
64
  TokenIsNotAllowed = "91721"
53
65
  TokenIsRequired = "91722"
54
66
  TokenIsTooLong = "91720"
67
+ VenmoSDKPaymentMethodCodeCardTypeIsNotAccepted = "91726"
55
68
 
56
69
  module Options
57
70
  UpdateExistingTokenIsInvalid = "91723"
71
+ VerificationMerchantAccountIdIsInvalid = "91728"
58
72
  end
59
73
  end
60
74
 
@@ -64,6 +78,7 @@ module Braintree
64
78
  CustomFieldIsInvalid = "91602"
65
79
  CustomFieldIsTooLong = "81603"
66
80
  EmailIsInvalid = "81604"
81
+ EmailFormatIsInvalid = "81604"
67
82
  EmailIsRequired = "81606"
68
83
  EmailIsTooLong = "81605"
69
84
  FaxIsTooLong = "81607"
@@ -77,12 +92,16 @@ module Braintree
77
92
  LastNameIsTooLong = "81613"
78
93
  PhoneIsTooLong = "81614"
79
94
  WebsiteIsInvalid = "81616"
95
+ WebsiteFormatIsInvalid = "81616"
80
96
  WebsiteIsTooLong = "81615"
81
97
  end
82
98
 
83
99
  module Descriptor
84
- PhoneFormatIsInvalid = "92202"
100
+ DynamicDescriptorsDisabled = "92203"
101
+ InternationalPhoneFormatIsInvalid = "92205"
102
+ InternationalNameFormatIsInvalid = "92204"
85
103
  NameFormatIsInvalid = "92201"
104
+ PhoneFormatIsInvalid = "92202"
86
105
  end
87
106
 
88
107
  module SettlementBatchSummary
@@ -141,6 +160,7 @@ module Braintree
141
160
  InconsistentNumberOfBillingCycles = "92018"
142
161
  InheritedFromIdIsInvalid = "92013"
143
162
  InheritedFromIdIsRequired = "92014"
163
+ Missing = "92024"
144
164
  NumberOfBillingCyclesCannotBeBlank = "92017"
145
165
  NumberOfBillingCyclesIsInvalid = "92005"
146
166
  NumberOfBillingCyclesMustBeGreaterThanZero = "92019"
@@ -154,6 +174,7 @@ module Braintree
154
174
  module Transaction
155
175
  AmountCannotBeNegative = "81501"
156
176
  AmountIsInvalid = "81503"
177
+ AmountFormatIsInvalid = "81503"
157
178
  AmountIsRequired = "81502"
158
179
  AmountIsTooLarge = "81528"
159
180
  AmountMustBeGreaterThanZero = "81531"
@@ -76,6 +76,8 @@ module Braintree
76
76
  end
77
77
  response
78
78
  end
79
+ rescue OpenSSL::SSL::SSLError
80
+ raise Braintree::SSLCertificateError
79
81
  end
80
82
 
81
83
  def _body(response)
@@ -101,9 +103,10 @@ module Braintree
101
103
  if preverify_ok != true || ssl_context.error != 0
102
104
  err_msg = "SSL Verification failed -- Preverify: #{preverify_ok}, Error: #{ssl_context.error_string} (#{ssl_context.error})"
103
105
  @config.logger.error err_msg
104
- raise SSLCertificateError.new(err_msg)
106
+ false
107
+ else
108
+ true
105
109
  end
106
- true
107
110
  end
108
111
  end
109
112
  end
@@ -0,0 +1,19 @@
1
+ module Braintree
2
+ module Test
3
+ module VenmoSDK
4
+ def self.generate_test_payment_method_code(card_number)
5
+ "stub-#{card_number}"
6
+ end
7
+
8
+ AmExPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::AmExes.first)
9
+ DiscoverPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::Discovers.first)
10
+ JCBPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::JCBs.first)
11
+ MasterCardPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::MasterCards.first)
12
+ VisaPaymentMethodCode = generate_test_payment_method_code(CreditCardNumbers::Visas.first)
13
+ InvalidPaymentMethodCode = "stub-invalid-payment-method-code"
14
+
15
+ Session = "stub-session"
16
+ InvalidSession = "stub-invalid-session"
17
+ end
18
+ end
19
+ end
@@ -48,6 +48,7 @@ module Braintree
48
48
  attr_reader :currency_iso_code
49
49
  attr_reader :custom_fields
50
50
  attr_reader :cvv_response_code
51
+ attr_reader :disbursement_details
51
52
  attr_reader :descriptor
52
53
  attr_reader :gateway_rejection_reason
53
54
  attr_reader :merchant_account_id
@@ -176,6 +177,7 @@ module Braintree
176
177
  @subscription_details = SubscriptionDetails.new(@subscription)
177
178
  @customer_details = CustomerDetails.new(@customer)
178
179
  @billing_details = AddressDetails.new(@billing)
180
+ @disbursement_details = DisbursementDetails.new(@disbursement_details)
179
181
  @shipping_details = AddressDetails.new(@shipping)
180
182
  @status_history = attributes[:status_history] ? attributes[:status_history].map { |s| StatusDetails.new(s) } : []
181
183
  @tax_amount = Util.to_big_decimal(tax_amount)
@@ -223,6 +225,11 @@ module Braintree
223
225
  !@refund_id.nil?
224
226
  end
225
227
 
228
+ # Returns true if the transaction has been disbursed. False otherwise.
229
+ def disbursed?
230
+ @disbursement_details.valid?
231
+ end
232
+
226
233
  def refund_id
227
234
  warn "[DEPRECATED] Transaction.refund_id is deprecated. Please use TransparentRedirect.refund_ids"
228
235
  @refund_id
@@ -0,0 +1,21 @@
1
+ module Braintree
2
+ class Transaction
3
+ class DisbursementDetails # :nodoc:
4
+ include BaseModule
5
+
6
+ attr_reader :disbursement_date, :settlement_amount, :settlement_currency_iso_code, :settlement_currency_exchange_rate
7
+
8
+ def initialize(attributes)
9
+ set_instance_variables_from_hash attributes unless attributes.nil?
10
+ end
11
+
12
+ def funds_held?
13
+ @funds_held
14
+ end
15
+
16
+ def valid?
17
+ !disbursement_date.nil?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -62,6 +62,7 @@ module Braintree
62
62
 
63
63
  range_fields :amount, :created_at, :authorization_expired_at, :authorized_at,
64
64
  :failed_at, :gateway_rejected_at, :processor_declined_at,
65
- :settled_at, :submitted_for_settlement_at, :voided_at
65
+ :settled_at, :submitted_for_settlement_at, :voided_at,
66
+ :disbursement_date
66
67
  end
67
68
  end
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 2
4
- Minor = 22
4
+ Minor = 23
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
data/lib/braintree/xml.rb CHANGED
@@ -9,4 +9,3 @@ module Braintree
9
9
  end
10
10
  end
11
11
  end
12
-
data/spec/httpsd.pid CHANGED
@@ -1 +1 @@
1
- 95171
1
+ 11041
@@ -23,6 +23,8 @@ describe Braintree::CreditCard do
23
23
  credit_card.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
24
24
  credit_card.expiration_date.should == "05/2009"
25
25
  credit_card.unique_number_identifier.should =~ /\A\w{32}\z/
26
+ credit_card.venmo_sdk?.should == false
27
+ credit_card.image_url.should_not be_nil
26
28
  end
27
29
 
28
30
  it "can provide expiration month and year separately" do
@@ -378,6 +380,65 @@ describe Braintree::CreditCard do
378
380
  end
379
381
  end
380
382
 
383
+ context "venmo_sdk" do
384
+ describe "venmo_sdk_payment_method_code" do
385
+ it "can pass a venmo sdk payment method code" do
386
+ customer = Braintree::Customer.create!
387
+ result = Braintree::CreditCard.create(
388
+ :customer_id => customer.id,
389
+ :venmo_sdk_payment_method_code => Braintree::Test::VenmoSDK::VisaPaymentMethodCode
390
+ )
391
+ result.success?.should == true
392
+ result.credit_card.venmo_sdk?.should == true
393
+ result.credit_card.bin.should == "400934"
394
+ result.credit_card.last_4.should == "1881"
395
+ end
396
+
397
+ it "success? returns false when given an invalid venmo sdk payment method code" do
398
+ customer = Braintree::Customer.create!
399
+ result = Braintree::CreditCard.create(
400
+ :customer_id => customer.id,
401
+ :venmo_sdk_payment_method_code => Braintree::Test::VenmoSDK::InvalidPaymentMethodCode
402
+ )
403
+
404
+ result.success?.should == false
405
+ result.message.should == "Invalid VenmoSDK payment method code"
406
+ result.errors.first.code.should == "91727"
407
+ end
408
+ end
409
+
410
+ describe "venmo_sdk_session" do
411
+ it "venmo_sdk? returns true when given a valid session" do
412
+ customer = Braintree::Customer.create!
413
+ result = Braintree::CreditCard.create(
414
+ :customer_id => customer.id,
415
+ :number => Braintree::Test::CreditCardNumbers::Visa,
416
+ :expiration_date => "05/2009",
417
+ :cvv => "100",
418
+ :options => {
419
+ :venmo_sdk_session => Braintree::Test::VenmoSDK::Session
420
+ }
421
+ )
422
+ result.success?.should == true
423
+ result.credit_card.venmo_sdk?.should == true
424
+ end
425
+
426
+ it "venmo_sdk? returns false when given an invalid session" do
427
+ customer = Braintree::Customer.create!
428
+ result = Braintree::CreditCard.create(
429
+ :customer_id => customer.id,
430
+ :number => Braintree::Test::CreditCardNumbers::Visa,
431
+ :expiration_date => "05/2009",
432
+ :cvv => "100",
433
+ :options => {
434
+ :venmo_sdk_session => Braintree::Test::VenmoSDK::InvalidSession
435
+ }
436
+ )
437
+ result.success?.should == true
438
+ result.credit_card.venmo_sdk?.should == false
439
+ end
440
+ end
441
+ end
381
442
  end
382
443
 
383
444
  describe "self.create!" do
@@ -336,6 +336,21 @@ describe Braintree::Customer do
336
336
  result.success?.should == false
337
337
  result.errors.for(:customer).on(:custom_fields)[0].message.should == "Custom field is invalid: spouse_name."
338
338
  end
339
+
340
+ describe "venmo_sdk" do
341
+ it "can create a customer with a venmo sdk payment method code" do
342
+ result = Braintree::Customer.create(
343
+ :first_name => "Steve",
344
+ :last_name => "Hamlin",
345
+ :credit_card => {
346
+ :venmo_sdk_payment_method_code => Braintree::Test::VenmoSDK::VisaPaymentMethodCode
347
+ }
348
+ )
349
+ result.success?.should == true
350
+ result.customer.credit_cards.first.bin.should == "400934"
351
+ result.customer.credit_cards.first.last_4.should == "1881"
352
+ end
353
+ end
339
354
  end
340
355
 
341
356
  describe "self.create!" do
@@ -1041,4 +1056,31 @@ describe Braintree::Customer do
1041
1056
  customer.website.should == "new.website.com"
1042
1057
  end
1043
1058
  end
1059
+
1060
+ describe "default_credit_card" do
1061
+ it "should return the default credit card for a given customer" do
1062
+ customer = Braintree::Customer.create!(
1063
+ :credit_card => {
1064
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1065
+ :expiration_date => "12/2015",
1066
+ :options => {
1067
+ :make_default => false
1068
+ }
1069
+ }
1070
+ )
1071
+
1072
+ default_credit_card = Braintree::CreditCard.create!(
1073
+ :customer_id => customer.id,
1074
+ :number => Braintree::Test::CreditCardNumbers::MasterCard,
1075
+ :expiration_date => "11/2015",
1076
+ :options => {
1077
+ :make_default => true
1078
+ }
1079
+ )
1080
+
1081
+ customer = Braintree::Customer.find(customer.id)
1082
+
1083
+ customer.default_credit_card.should == default_credit_card
1084
+ end
1085
+ end
1044
1086
  end
@@ -93,11 +93,11 @@ describe Braintree::Http do
93
93
  start_ssl_server do
94
94
  expect do
95
95
  config.http._http_do(Net::HTTP::Get, "/login")
96
- end.to raise_error(Braintree::SSLCertificateError, /Preverify: false, Error: self signed certificate/)
96
+ end.to raise_error(Braintree::SSLCertificateError)
97
97
  end
98
98
  end
99
99
 
100
- it "rejets when the certificate is signed by a different (but valid) root CA" do
100
+ it "rejects when the certificate is signed by a different (but valid) root CA" do
101
101
  # Random CA root file from a different certificate authority
102
102
  config = Braintree::Configuration.instantiate
103
103
  config.stub(:ca_file).and_return(
@@ -109,7 +109,7 @@ describe Braintree::Http do
109
109
  start_ssl_server do
110
110
  expect do
111
111
  config.http._http_do(Net::HTTP::Get, "/login")
112
- end.to raise_error(Braintree::SSLCertificateError, /Preverify: false, Error: self signed certificate/)
112
+ end.to raise_error(Braintree::SSLCertificateError)
113
113
  end
114
114
  end
115
115
 
@@ -160,19 +160,15 @@ describe Braintree::Http do
160
160
  end
161
161
 
162
162
  describe "self._verify_ssl_certificate" do
163
- it "raises if preverify is false" do
163
+ it "is false if preverify is false" do
164
164
  context = OpenSSL::X509::StoreContext.new(OpenSSL::X509::Store.new)
165
- expect do
166
- Braintree::Configuration.instantiate.http._verify_ssl_certificate(false, context)
167
- end.to raise_error(Braintree::SSLCertificateError)
165
+ Braintree::Configuration.instantiate.http._verify_ssl_certificate(false, context).should == false
168
166
  end
169
167
 
170
- it "raise if ssl_context doesn't have an error code of 0" do
168
+ it "returns false if ssl_context doesn't have an error code of 0" do
171
169
  context = OpenSSL::X509::StoreContext.new(OpenSSL::X509::Store.new)
172
170
  context.error = 19 # ca_file incorrect, self-signed
173
- expect do
174
- Braintree::Configuration.instantiate.http._verify_ssl_certificate(true, context)
175
- end.to raise_error(Braintree::SSLCertificateError)
171
+ Braintree::Configuration.instantiate.http._verify_ssl_certificate(true, context).should == false
176
172
  end
177
173
 
178
174
  it "doesn't raise if there is no error" do
@@ -190,9 +186,7 @@ describe Braintree::Http do
190
186
  utc_or_gmt = Time.now.utc.strftime("%Z")
191
187
  context = OpenSSL::X509::StoreContext.new(OpenSSL::X509::Store.new)
192
188
  context.error = 19
193
- expect do
194
- Braintree::Configuration.instantiate.http._verify_ssl_certificate(false, context)
195
- end.to raise_error(Braintree::SSLCertificateError)
189
+ Braintree::Configuration.instantiate.http._verify_ssl_certificate(false, context).should == false
196
190
  output.string.should include("SSL Verification failed -- Preverify: false, Error: self signed certificate in certificate chain (19)")
197
191
  ensure
198
192
  Braintree::Configuration.logger = old_logger
@@ -208,7 +202,7 @@ describe Braintree::Http do
208
202
  context = OpenSSL::X509::StoreContext.new(OpenSSL::X509::Store.new)
209
203
  expect do
210
204
  Braintree::Configuration.instantiate.http._verify_ssl_certificate(true, context)
211
- end.to_not raise_error(Braintree::SSLCertificateError)
205
+ end.to_not raise_error(OpenSSL::SSL::SSLError)
212
206
  output.string.should == ""
213
207
  ensure
214
208
  Braintree::Configuration.logger = old_logger
@@ -1119,6 +1119,41 @@ describe Braintree::Subscription do
1119
1119
  end
1120
1120
  end
1121
1121
 
1122
+ describe "search on merchant account id" do
1123
+ it "searches on merchant_account_id" do
1124
+ id = rand(36**8).to_s(36)
1125
+ subscription = Braintree::Subscription.create(
1126
+ :payment_method_token => @credit_card.token,
1127
+ :plan_id => SpecHelper::TrialPlan[:id],
1128
+ :id => "subscription1_#{id}",
1129
+ :price => "11.38"
1130
+ ).subscription
1131
+
1132
+ collection = Braintree::Subscription.search do |search|
1133
+ search.merchant_account_id.is subscription.merchant_account_id
1134
+ search.price.is "11.38"
1135
+ end
1136
+
1137
+ # not testing for specific number since the
1138
+ # create subscriptions accumulate over time
1139
+ collection.maximum_size.should >= 1
1140
+
1141
+ collection = Braintree::Subscription.search do |search|
1142
+ search.merchant_account_id.in subscription.merchant_account_id, "bogus_merchant_account_id"
1143
+ search.price.is "11.38"
1144
+ end
1145
+
1146
+ collection.maximum_size.should >= 1
1147
+
1148
+ collection = Braintree::Subscription.search do |search|
1149
+ search.merchant_account_id.is "bogus_merchant_account_id"
1150
+ search.price.is "11.38"
1151
+ end
1152
+
1153
+ collection.maximum_size.should == 0
1154
+ end
1155
+ end
1156
+
1122
1157
  describe "id" do
1123
1158
  it "works using the is operator" do
1124
1159
  id = rand(36**8).to_s(36)
@@ -583,6 +583,116 @@ describe Braintree::Transaction, "search" do
583
583
  end
584
584
  end
585
585
 
586
+ context "disbursement_date" do
587
+ it "searches on disbursement_date in UTC" do
588
+ disbursement_time = Time.parse("2013-04-10 00:00:00 UTC")
589
+ transaction_id = "deposittransaction"
590
+
591
+ collection = Braintree::Transaction.search do |search|
592
+ search.id.is transaction_id
593
+ search.disbursement_date.between(
594
+ disbursement_time - 60,
595
+ disbursement_time + 60
596
+ )
597
+ end
598
+
599
+ collection.maximum_size.should == 1
600
+ collection.first.id.should == transaction_id
601
+
602
+ collection = Braintree::Transaction.search do |search|
603
+ search.id.is transaction_id
604
+ search.disbursement_date >= disbursement_time - 1
605
+ end
606
+
607
+ collection.maximum_size.should == 1
608
+ collection.first.id.should == transaction_id
609
+
610
+ collection = Braintree::Transaction.search do |search|
611
+ search.id.is transaction_id
612
+ search.disbursement_date <= disbursement_time + 1
613
+ end
614
+
615
+ collection.maximum_size.should == 1
616
+ collection.first.id.should == transaction_id
617
+
618
+ collection = Braintree::Transaction.search do |search|
619
+ search.id.is transaction_id
620
+ search.disbursement_date.between(
621
+ disbursement_time - 300,
622
+ disbursement_time - 100
623
+ )
624
+ end
625
+
626
+ collection.maximum_size.should == 0
627
+
628
+ collection = Braintree::Transaction.search do |search|
629
+ search.id.is transaction_id
630
+ search.disbursement_date.is disbursement_time
631
+ end
632
+
633
+ collection.maximum_size.should == 1
634
+ collection.first.id.should == transaction_id
635
+ end
636
+
637
+ it "searches on disbursement_date in local time" do
638
+ now = Time.parse("2013-04-09 18:00:00 CST")
639
+ transaction_id = "deposittransaction"
640
+
641
+ collection = Braintree::Transaction.search do |search|
642
+ search.id.is transaction_id
643
+ search.disbursement_date.between(
644
+ now - 60,
645
+ now + 60
646
+ )
647
+ end
648
+
649
+ collection.maximum_size.should == 1
650
+ collection.first.id.should == transaction_id
651
+
652
+ collection = Braintree::Transaction.search do |search|
653
+ search.id.is transaction_id
654
+ search.disbursement_date >= now - 60
655
+ end
656
+
657
+ collection.maximum_size.should == 1
658
+ collection.first.id.should == transaction_id
659
+
660
+ collection = Braintree::Transaction.search do |search|
661
+ search.id.is transaction_id
662
+ search.disbursement_date <= now + 60
663
+ end
664
+
665
+ collection.maximum_size.should == 1
666
+ collection.first.id.should == transaction_id
667
+
668
+ collection = Braintree::Transaction.search do |search|
669
+ search.id.is transaction_id
670
+ search.disbursement_date.between(
671
+ now - 300,
672
+ now - 100
673
+ )
674
+ end
675
+
676
+ collection.maximum_size.should == 0
677
+ end
678
+
679
+ it "searches on disbursement_date with date ranges" do
680
+ disbursement_date = Date.new(2013, 4, 10)
681
+ transaction_id = "deposittransaction"
682
+
683
+ collection = Braintree::Transaction.search do |search|
684
+ search.id.is transaction_id
685
+ search.disbursement_date.between(
686
+ disbursement_date - 1,
687
+ disbursement_date + 1
688
+ )
689
+ end
690
+
691
+ collection.maximum_size.should == 1
692
+ collection.first.id.should == transaction_id
693
+ end
694
+ end
695
+
586
696
  context "status date ranges" do
587
697
  it "finds transactions authorized in a given range" do
588
698
  transaction = Braintree::Transaction.sale!(
@@ -121,16 +121,15 @@ describe Braintree::Transaction do
121
121
  end
122
122
 
123
123
  describe "self.create" do
124
-
125
124
  describe "card type indicators" do
126
125
  it "sets the prepaid field if the card is prepaid" do
127
126
  result = Braintree::Transaction.create(
128
127
  :type => "sale",
129
128
  :amount => 1_00,
130
129
  :credit_card => {
131
- :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
132
- :expiration_date => "05/2009"
133
- }
130
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
131
+ :expiration_date => "05/2009"
132
+ }
134
133
  )
135
134
  result.transaction.credit_card_details.prepaid.should == Braintree::CreditCard::Prepaid::Yes
136
135
  end
@@ -873,6 +872,19 @@ describe Braintree::Transaction do
873
872
  end
874
873
  end
875
874
  end
875
+
876
+ describe "venmo_sdk" do
877
+ it "can create a card with a venmo sdk payment method code" do
878
+ result = Braintree::Transaction.create(
879
+ :type => "sale",
880
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
881
+ :venmo_sdk_payment_method_code => Braintree::Test::VenmoSDK::VisaPaymentMethodCode
882
+ )
883
+ result.success?.should == true
884
+ result.transaction.credit_card_details.bin.should == "400934"
885
+ result.transaction.credit_card_details.last_4.should == "1881"
886
+ end
887
+ end
876
888
  end
877
889
 
878
890
  describe "self.create!" do
@@ -994,6 +1006,7 @@ describe Braintree::Transaction do
994
1006
  end.to raise_error(Braintree::ValidationsFailed)
995
1007
  end
996
1008
  end
1009
+
997
1010
  describe "self.sale" do
998
1011
  it "returns a successful result with type=sale if successful" do
999
1012
  result = Braintree::Transaction.sale(
@@ -1733,6 +1746,36 @@ describe Braintree::Transaction do
1733
1746
  Braintree::Transaction.find("invalid-id")
1734
1747
  end.to raise_error(Braintree::NotFoundError, 'transaction with id "invalid-id" not found')
1735
1748
  end
1749
+
1750
+ context "disbursement_details" do
1751
+ it "includes disbursement_details on found transactions" do
1752
+ found_transaction = Braintree::Transaction.find("deposittransaction")
1753
+
1754
+ found_transaction.disbursed?.should == true
1755
+ disbursement = found_transaction.disbursement_details
1756
+
1757
+ disbursement.disbursement_date.should == "2013-04-10"
1758
+ disbursement.settlement_amount.should == "100.00"
1759
+ disbursement.settlement_currency_iso_code.should == "USD"
1760
+ disbursement.settlement_currency_exchange_rate.should == "1"
1761
+ disbursement.funds_held?.should == false
1762
+ end
1763
+
1764
+ it "is not disbursed" do
1765
+ result = Braintree::Transaction.create(
1766
+ :type => "sale",
1767
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1768
+ :credit_card => {
1769
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1770
+ :expiration_date => "05/2009"
1771
+ }
1772
+ )
1773
+ result.success?.should == true
1774
+ created_transaction = result.transaction
1775
+
1776
+ created_transaction.disbursed?.should == false
1777
+ end
1778
+ end
1736
1779
  end
1737
1780
 
1738
1781
  describe "self.void" do
data/spec/spec_helper.rb CHANGED
@@ -3,7 +3,7 @@ unless defined?(SPEC_HELPER_LOADED)
3
3
 
4
4
  project_root = File.expand_path(File.dirname(__FILE__) + "/..")
5
5
  require "rubygems"
6
- gem "libxml-ruby", ENV["LIBXML_VERSION"] || "1.1.3"
6
+ gem "libxml-ruby", ENV["LIBXML_VERSION"] || (RUBY_VERSION == "1.9.3" ? "2.6.0" : "1.1.3")
7
7
  require "libxml"
8
8
  gem "builder", ENV["BUILDER_VERSION"] || "2.1.2"
9
9
  braintree_lib = "#{project_root}/lib"
@@ -34,6 +34,7 @@ unless defined?(SPEC_HELPER_LOADED)
34
34
 
35
35
  DefaultMerchantAccountId = "sandbox_credit_card"
36
36
  NonDefaultMerchantAccountId = "sandbox_credit_card_non_default"
37
+ NonDefaultSubMerchantAccountId = "sandbox_sub_merchant_account"
37
38
 
38
39
  TrialPlan = {
39
40
  :description => "Plan for integration tests -- with trial",
@@ -241,4 +241,12 @@ describe Braintree::Configuration do
241
241
  Braintree::Configuration.instantiate.user_agent.should == "Braintree Ruby Gem #{Braintree::Version::String}"
242
242
  end
243
243
  end
244
+
245
+ describe "inspect" do
246
+ it "masks the private_key" do
247
+ config = Braintree::Configuration.new(:private_key => "secret_key")
248
+ config.inspect.should include('@private_key="[FILTERED]"')
249
+ config.inspect.should_not include('secret_key')
250
+ end
251
+ end
244
252
  end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::Transaction::DisbursementDetails do
4
+ describe "valid?" do
5
+ it "returns true if disbursement details are initialized" do
6
+ details = Braintree::Transaction::DisbursementDetails.new(
7
+ :disbursement_date => Date.new(2013, 4, 1)
8
+ )
9
+ details.valid?.should == true
10
+ end
11
+ it "returns true if disbursement details are initialized" do
12
+ details = Braintree::Transaction::DisbursementDetails.new(
13
+ :disbursement_date => nil
14
+ )
15
+ details.valid?.should == false
16
+ end
17
+ end
18
+ end
@@ -85,6 +85,25 @@ describe Braintree::Transaction do
85
85
  transaction.customer_details.fax.should == "012-161-8055"
86
86
  end
87
87
 
88
+ it "sets up disbursement attributes in disbursement_details" do
89
+ transaction = Braintree::Transaction._new(
90
+ :gateway,
91
+ :disbursement_details => {
92
+ :disbursement_date => "2013-04-03",
93
+ :settlement_amount => "120.00",
94
+ :settlement_currency_iso_code => "USD",
95
+ :settlement_currency_exchange_rate => "1",
96
+ :funds_held => false
97
+ }
98
+ )
99
+ disbursement = transaction.disbursement_details
100
+ disbursement.disbursement_date.should == "2013-04-03"
101
+ disbursement.settlement_amount.should == "120.00"
102
+ disbursement.settlement_currency_iso_code.should == "USD"
103
+ disbursement.settlement_currency_exchange_rate.should == "1"
104
+ disbursement.funds_held?.should == false
105
+ end
106
+
88
107
  it "sets up credit card attributes in credit_card_details" do
89
108
  transaction = Braintree::Transaction._new(
90
109
  :gateway,
@@ -36,6 +36,15 @@ describe Braintree::Xml::Parser do
36
36
  xml.should parse_to(:root => {:created_at => Time.utc(2009, 10, 28, 10, 19, 49)})
37
37
  end
38
38
 
39
+ it "doesn't typecast dates" do
40
+ xml = <<-END
41
+ <root>
42
+ <created-at type="date">2009-10-28</created-at>
43
+ </root>
44
+ END
45
+ xml.should parse_to(:root => {:created_at => "2009-10-28"})
46
+ end
47
+
39
48
  it "builds an array if type=array" do
40
49
  xml = <<-END
41
50
  <root>
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- hash: 87
5
- prerelease: false
4
+ hash: 83
5
+ prerelease:
6
6
  segments:
7
7
  - 2
8
- - 22
8
+ - 23
9
9
  - 0
10
- version: 2.22.0
10
+ version: 2.23.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Braintree
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-12-20 00:00:00 -06:00
19
- default_executable:
18
+ date: 2013-05-01 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: builder
@@ -45,132 +44,134 @@ extra_rdoc_files: []
45
44
  files:
46
45
  - README.rdoc
47
46
  - LICENSE
47
+ - lib/braintree.rb
48
+ - lib/braintree/subscription_search.rb
49
+ - lib/braintree/modification.rb
50
+ - lib/braintree/errors.rb
51
+ - lib/braintree/test/credit_card.rb
52
+ - lib/braintree/test/transaction_amounts.rb
53
+ - lib/braintree/test/venmo_sdk.rb
54
+ - lib/braintree/webhook_testing.rb
55
+ - lib/braintree/webhook_testing_gateway.rb
56
+ - lib/braintree/advanced_search.rb
57
+ - lib/braintree/version.rb
48
58
  - lib/braintree/add_on.rb
49
- - lib/braintree/add_on_gateway.rb
50
- - lib/braintree/address/country_names.rb
51
59
  - lib/braintree/address.rb
52
- - lib/braintree/address_gateway.rb
53
- - lib/braintree/advanced_search.rb
54
- - lib/braintree/base_module.rb
55
- - lib/braintree/configuration.rb
56
- - lib/braintree/credit_card.rb
57
- - lib/braintree/credit_card_gateway.rb
58
- - lib/braintree/credit_card_verification.rb
59
- - lib/braintree/credit_card_verification_gateway.rb
60
- - lib/braintree/credit_card_verification_search.rb
61
- - lib/braintree/customer.rb
62
- - lib/braintree/customer_gateway.rb
63
- - lib/braintree/customer_search.rb
64
- - lib/braintree/descriptor.rb
65
60
  - lib/braintree/digest.rb
66
- - lib/braintree/discount.rb
67
- - lib/braintree/discount_gateway.rb
61
+ - lib/braintree/settlement_batch_summary.rb
68
62
  - lib/braintree/error_codes.rb
69
- - lib/braintree/error_result.rb
70
- - lib/braintree/errors.rb
63
+ - lib/braintree/discount.rb
64
+ - lib/braintree/webhook_notification.rb
65
+ - lib/braintree/settlement_batch_summary_gateway.rb
66
+ - lib/braintree/validation_error_collection.rb
67
+ - lib/braintree/credit_card_verification_gateway.rb
68
+ - lib/braintree/credit_card.rb
69
+ - lib/braintree/customer_search.rb
70
+ - lib/braintree/util.rb
71
+ - lib/braintree/transparent_redirect.rb
72
+ - lib/braintree/xml/generator.rb
73
+ - lib/braintree/xml/rexml.rb
74
+ - lib/braintree/xml/libxml.rb
75
+ - lib/braintree/xml/parser.rb
71
76
  - lib/braintree/exceptions.rb
72
- - lib/braintree/gateway.rb
73
- - lib/braintree/http.rb
74
- - lib/braintree/modification.rb
75
- - lib/braintree/plan.rb
76
- - lib/braintree/plan_gateway.rb
77
+ - lib/braintree/validation_error.rb
77
78
  - lib/braintree/resource_collection.rb
78
- - lib/braintree/settlement_batch.rb
79
- - lib/braintree/settlement_batch_summary.rb
80
- - lib/braintree/settlement_batch_summary_gateway.rb
81
- - lib/braintree/subscription.rb
79
+ - lib/braintree/xml.rb
80
+ - lib/braintree/credit_card_verification.rb
81
+ - lib/braintree/configuration.rb
82
+ - lib/braintree/transaction.rb
83
+ - lib/braintree/http.rb
84
+ - lib/braintree/address_gateway.rb
82
85
  - lib/braintree/subscription_gateway.rb
83
- - lib/braintree/subscription_search.rb
86
+ - lib/braintree/customer_gateway.rb
87
+ - lib/braintree/plan_gateway.rb
88
+ - lib/braintree/credit_card_verification_search.rb
84
89
  - lib/braintree/successful_result.rb
85
- - lib/braintree/test/credit_card.rb
86
- - lib/braintree/test/transaction_amounts.rb
87
- - lib/braintree/transaction/address_details.rb
88
- - lib/braintree/transaction/credit_card_details.rb
90
+ - lib/braintree/settlement_batch.rb
91
+ - lib/braintree/plan.rb
92
+ - lib/braintree/gateway.rb
93
+ - lib/braintree/transparent_redirect_gateway.rb
94
+ - lib/braintree/base_module.rb
95
+ - lib/braintree/add_on_gateway.rb
96
+ - lib/braintree/transaction/subscription_details.rb
97
+ - lib/braintree/transaction/disbursement_details.rb
89
98
  - lib/braintree/transaction/customer_details.rb
99
+ - lib/braintree/transaction/credit_card_details.rb
90
100
  - lib/braintree/transaction/status_details.rb
91
- - lib/braintree/transaction/subscription_details.rb
92
- - lib/braintree/transaction.rb
93
- - lib/braintree/transaction_gateway.rb
101
+ - lib/braintree/transaction/address_details.rb
94
102
  - lib/braintree/transaction_search.rb
95
- - lib/braintree/transparent_redirect.rb
96
- - lib/braintree/transparent_redirect_gateway.rb
97
- - lib/braintree/util.rb
98
- - lib/braintree/validation_error.rb
99
- - lib/braintree/validation_error_collection.rb
100
- - lib/braintree/version.rb
101
- - lib/braintree/webhook_notification.rb
103
+ - lib/braintree/error_result.rb
104
+ - lib/braintree/credit_card_gateway.rb
105
+ - lib/braintree/descriptor.rb
106
+ - lib/braintree/transaction_gateway.rb
107
+ - lib/braintree/subscription.rb
108
+ - lib/braintree/address/country_names.rb
102
109
  - lib/braintree/webhook_notification_gateway.rb
103
- - lib/braintree/webhook_testing.rb
104
- - lib/braintree/webhook_testing_gateway.rb
105
- - lib/braintree/xml/generator.rb
106
- - lib/braintree/xml/libxml.rb
107
- - lib/braintree/xml/parser.rb
108
- - lib/braintree/xml/rexml.rb
109
- - lib/braintree/xml.rb
110
- - lib/braintree.rb
110
+ - lib/braintree/customer.rb
111
+ - lib/braintree/discount_gateway.rb
112
+ - lib/ssl/www_braintreegateway_com.ca.crt
111
113
  - lib/ssl/sandbox_braintreegateway_com.ca.crt
112
114
  - lib/ssl/securetrust_ca.crt
113
- - lib/ssl/www_braintreegateway_com.ca.crt
114
- - spec/hacks/tcp_socket.rb
115
- - spec/httpsd.pid
116
- - spec/integration/braintree/add_on_spec.rb
117
- - spec/integration/braintree/address_spec.rb
118
- - spec/integration/braintree/advanced_search_spec.rb
119
- - spec/integration/braintree/credit_card_spec.rb
120
- - spec/integration/braintree/credit_card_verification_search_spec.rb
121
- - spec/integration/braintree/credit_card_verification_spec.rb
122
- - spec/integration/braintree/customer_search_spec.rb
123
- - spec/integration/braintree/customer_spec.rb
124
- - spec/integration/braintree/discount_spec.rb
125
- - spec/integration/braintree/error_codes_spec.rb
126
- - spec/integration/braintree/http_spec.rb
127
- - spec/integration/braintree/plan_spec.rb
128
- - spec/integration/braintree/settlement_batch_summary_spec.rb
129
- - spec/integration/braintree/subscription_spec.rb
130
- - spec/integration/braintree/test/transaction_amounts_spec.rb
131
- - spec/integration/braintree/transaction_search_spec.rb
132
- - spec/integration/braintree/transaction_spec.rb
133
- - spec/integration/braintree/transparent_redirect_spec.rb
134
- - spec/integration/spec_helper.rb
135
115
  - spec/script/httpsd.rb
136
- - spec/spec.opts
137
116
  - spec/spec_helper.rb
138
- - spec/ssl/certificate.crt
139
- - spec/ssl/geotrust_global.crt
140
- - spec/ssl/privateKey.key
141
- - spec/unit/braintree/address_spec.rb
142
- - spec/unit/braintree/base_module_spec.rb
143
- - spec/unit/braintree/configuration_spec.rb
144
- - spec/unit/braintree/credit_card_spec.rb
145
- - spec/unit/braintree/credit_card_verification_search_spec.rb
146
- - spec/unit/braintree/credit_card_verification_spec.rb
147
- - spec/unit/braintree/customer_spec.rb
148
- - spec/unit/braintree/digest_spec.rb
117
+ - spec/unit/spec_helper.rb
118
+ - spec/unit/braintree/transaction_search_spec.rb
149
119
  - spec/unit/braintree/error_result_spec.rb
150
- - spec/unit/braintree/errors_spec.rb
120
+ - spec/unit/braintree/xml_spec.rb
121
+ - spec/unit/braintree/customer_spec.rb
122
+ - spec/unit/braintree/transaction_spec.rb
123
+ - spec/unit/braintree/webhook_notification_spec.rb
151
124
  - spec/unit/braintree/http_spec.rb
152
- - spec/unit/braintree/modification_spec.rb
153
- - spec/unit/braintree/resource_collection_spec.rb
154
- - spec/unit/braintree/subscription_search_spec.rb
155
125
  - spec/unit/braintree/subscription_spec.rb
126
+ - spec/unit/braintree/credit_card_verification_search_spec.rb
127
+ - spec/unit/braintree/subscription_search_spec.rb
156
128
  - spec/unit/braintree/successful_result_spec.rb
157
- - spec/unit/braintree/transaction/credit_card_details_spec.rb
158
- - spec/unit/braintree/transaction/customer_details_spec.rb
159
- - spec/unit/braintree/transaction_search_spec.rb
160
- - spec/unit/braintree/transaction_spec.rb
161
- - spec/unit/braintree/transparent_redirect_spec.rb
162
- - spec/unit/braintree/util_spec.rb
163
- - spec/unit/braintree/validation_error_collection_spec.rb
129
+ - spec/unit/braintree/credit_card_verification_spec.rb
164
130
  - spec/unit/braintree/validation_error_spec.rb
165
- - spec/unit/braintree/webhook_notification_spec.rb
131
+ - spec/unit/braintree/resource_collection_spec.rb
166
132
  - spec/unit/braintree/xml/libxml_spec.rb
167
133
  - spec/unit/braintree/xml/parser_spec.rb
168
134
  - spec/unit/braintree/xml/rexml_spec.rb
169
- - spec/unit/braintree/xml_spec.rb
135
+ - spec/unit/braintree/configuration_spec.rb
136
+ - spec/unit/braintree/validation_error_collection_spec.rb
137
+ - spec/unit/braintree/errors_spec.rb
138
+ - spec/unit/braintree/modification_spec.rb
139
+ - spec/unit/braintree/util_spec.rb
140
+ - spec/unit/braintree/base_module_spec.rb
141
+ - spec/unit/braintree/address_spec.rb
142
+ - spec/unit/braintree/transparent_redirect_spec.rb
143
+ - spec/unit/braintree/transaction/deposit_details_spec.rb
144
+ - spec/unit/braintree/transaction/credit_card_details_spec.rb
145
+ - spec/unit/braintree/transaction/customer_details_spec.rb
146
+ - spec/unit/braintree/credit_card_spec.rb
147
+ - spec/unit/braintree/digest_spec.rb
170
148
  - spec/unit/braintree_spec.rb
171
- - spec/unit/spec_helper.rb
149
+ - spec/hacks/tcp_socket.rb
150
+ - spec/httpsd.pid
151
+ - spec/integration/spec_helper.rb
152
+ - spec/integration/braintree/settlement_batch_summary_spec.rb
153
+ - spec/integration/braintree/transaction_search_spec.rb
154
+ - spec/integration/braintree/test/transaction_amounts_spec.rb
155
+ - spec/integration/braintree/customer_spec.rb
156
+ - spec/integration/braintree/transaction_spec.rb
157
+ - spec/integration/braintree/add_on_spec.rb
158
+ - spec/integration/braintree/http_spec.rb
159
+ - spec/integration/braintree/subscription_spec.rb
160
+ - spec/integration/braintree/credit_card_verification_search_spec.rb
161
+ - spec/integration/braintree/credit_card_verification_spec.rb
162
+ - spec/integration/braintree/advanced_search_spec.rb
163
+ - spec/integration/braintree/customer_search_spec.rb
164
+ - spec/integration/braintree/plan_spec.rb
165
+ - spec/integration/braintree/error_codes_spec.rb
166
+ - spec/integration/braintree/address_spec.rb
167
+ - spec/integration/braintree/transparent_redirect_spec.rb
168
+ - spec/integration/braintree/credit_card_spec.rb
169
+ - spec/integration/braintree/discount_spec.rb
170
+ - spec/spec.opts
171
+ - spec/ssl/geotrust_global.crt
172
+ - spec/ssl/certificate.crt
173
+ - spec/ssl/privateKey.key
172
174
  - braintree.gemspec
173
- has_rdoc: true
174
175
  homepage: http://www.braintreepayments.com/
175
176
  licenses: []
176
177
 
@@ -200,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
200
201
  requirements: []
201
202
 
202
203
  rubyforge_project: braintree
203
- rubygems_version: 1.3.7
204
+ rubygems_version: 1.8.25
204
205
  signing_key:
205
206
  specification_version: 3
206
207
  summary: Braintree Gateway Ruby Client Library