braintree 2.22.0 → 2.23.0

Sign up to get free protection for your applications and to get access to all the features.
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