braintree 2.6.3 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/braintree.rb CHANGED
@@ -32,6 +32,8 @@ require File.dirname(__FILE__) + "/braintree/credit_card_gateway"
32
32
  require File.dirname(__FILE__) + "/braintree/credit_card_verification"
33
33
  require File.dirname(__FILE__) + "/braintree/customer"
34
34
  require File.dirname(__FILE__) + "/braintree/customer_gateway"
35
+ require File.dirname(__FILE__) + "/braintree/customer_search"
36
+ require File.dirname(__FILE__) + "/braintree/descriptor"
35
37
  require File.dirname(__FILE__) + "/braintree/digest"
36
38
  require File.dirname(__FILE__) + "/braintree/discount"
37
39
  require File.dirname(__FILE__) + "/braintree/error_codes"
@@ -67,6 +67,11 @@ module Braintree
67
67
  return_object_or_raise(:transaction) { sale(customer_id, transaction_attributes) }
68
68
  end
69
69
 
70
+ # See http://www.braintreepaymentsolutions.com/docs/ruby/customers/search
71
+ def self.search(&block)
72
+ Configuration.gateway.customer.search(&block)
73
+ end
74
+
70
75
  # Returns a ResourceCollection of transactions for the customer with the given +customer_id+.
71
76
  def self.transactions(customer_id, options = {})
72
77
  Configuration.gateway.customer.transactions(customer_id, options = {})
@@ -7,7 +7,7 @@ module Braintree
7
7
 
8
8
  def all
9
9
  response = @config.http.post "/customers/advanced_search_ids"
10
- ResourceCollection.new(response) { |ids| _fetch_customers(ids) }
10
+ ResourceCollection.new(response) { |ids| _fetch_customers(CustomerSearch.new, ids) }
11
11
  end
12
12
 
13
13
  def create(attributes = {})
@@ -40,6 +40,14 @@ module Braintree
40
40
  raise NotFoundError, "customer with id #{customer_id.inspect} not found"
41
41
  end
42
42
 
43
+ def search(&block)
44
+ search = CustomerSearch.new
45
+ block.call(search) if block
46
+
47
+ response = @config.http.post "/customers/advanced_search_ids", {:search => search.to_hash}
48
+ ResourceCollection.new(response) { |ids| _fetch_customers(search, ids) }
49
+ end
50
+
43
51
  def transactions(customer_id, options = {})
44
52
  response = @config.http.post "/customers/#{customer_id}/transaction_ids"
45
53
  ResourceCollection.new(response) { |ids| _fetch_transactions(customer_id, ids) }
@@ -93,8 +101,9 @@ module Braintree
93
101
  end
94
102
  end
95
103
 
96
- def _fetch_customers(ids) # :nodoc:
97
- response = @config.http.post "/customers/advanced_search", {:search => {:ids => ids}}
104
+ def _fetch_customers(search, ids) # :nodoc:
105
+ search.ids.in ids
106
+ response = @config.http.post "/customers/advanced_search", {:search => search.to_hash}
98
107
  attributes = response[:customers]
99
108
  Util.extract_attribute_as_array(attributes, :customer).map { |attrs| Customer._new(@gateway, attrs) }
100
109
  end
@@ -0,0 +1,31 @@
1
+ module Braintree
2
+ class CustomerSearch < AdvancedSearch # :nodoc:
3
+ text_fields(
4
+ :address_extended_address,
5
+ :address_first_name,
6
+ :address_last_name,
7
+ :address_locality,
8
+ :address_postal_code,
9
+ :address_region,
10
+ :address_street_address,
11
+ :cardholder_name,
12
+ :company,
13
+ :email,
14
+ :fax,
15
+ :first_name,
16
+ :id,
17
+ :last_name,
18
+ :payment_method_token,
19
+ :phone,
20
+ :website
21
+ )
22
+
23
+ equality_fields :credit_card_expiration_date
24
+
25
+ partial_match_fields :credit_card_number
26
+
27
+ multiple_value_field :ids
28
+
29
+ range_fields :created_at
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ module Braintree
2
+ class Descriptor # :nodoc:
3
+ include BaseModule
4
+
5
+ attr_reader :name, :phone
6
+
7
+ def initialize(attributes)
8
+ set_instance_variables_from_hash attributes unless attributes.nil?
9
+ end
10
+ end
11
+ end
@@ -78,6 +78,11 @@ module Braintree
78
78
  WebsiteIsTooLong = "81615"
79
79
  end
80
80
 
81
+ module Descriptor
82
+ PhoneFormatIsInvalid = "92202"
83
+ NameFormatIsInvalid = "92201"
84
+ end
85
+
81
86
  # See http://www.braintreepaymentsolutions.com/docs/ruby/subscriptions/validations
82
87
  module Subscription
83
88
  BillingDayOfMonthCannotBeUpdated = "91918"
@@ -102,6 +107,7 @@ module Braintree
102
107
  PaymentMethodTokenCardTypeIsNotAccepted = "91902"
103
108
  PaymentMethodTokenIsInvalid = "91903"
104
109
  PaymentMethodTokenNotAssociatedWithCustomer = "91905"
110
+ PlanBillingFrequencyCannotBeUpdated = "91922"
105
111
  PlanIdIsInvalid = "91904"
106
112
  PriceCannotBeBlank = "81903"
107
113
  PriceFormatIsInvalid = "81904"
@@ -136,8 +142,8 @@ module Braintree
136
142
  # See http://www.braintreepaymentsolutions.com/docs/ruby/transactions/validations
137
143
  module Transaction
138
144
  AmountCannotBeNegative = "81501"
139
- AmountIsRequired = "81502"
140
145
  AmountIsInvalid = "81503"
146
+ AmountIsRequired = "81502"
141
147
  AmountIsTooLarge = "81528"
142
148
  AmountMustBeGreaterThanZero = "81531"
143
149
  BillingAddressConflict = "91530"
@@ -146,15 +152,15 @@ module Braintree
146
152
  CannotRefundUnlessSettled = "91506"
147
153
  CannotSubmitForSettlement = "91507"
148
154
  CreditCardIsRequired = "91508"
149
- CustomerDefaultPaymentMethodCardTypeIsNotAccepted = "81509"
150
155
  CustomFieldIsInvalid = "91526"
151
156
  CustomFieldIsTooLong = "81527"
152
- CustomerIdIsInvalid = "91510"
157
+ CustomerDefaultPaymentMethodCardTypeIsNotAccepted = "81509"
153
158
  CustomerDoesNotHaveCreditCard = "91511"
159
+ CustomerIdIsInvalid = "91510"
154
160
  HasAlreadyBeenRefunded = "91512"
155
161
  MerchantAccountIdIsInvalid = "91513"
156
- MerchantAccountNameIsInvalid = "91513" # Deprecated
157
162
  MerchantAccountIsSuspended = "91514"
163
+ MerchantAccountNameIsInvalid = "91513" # Deprecated
158
164
  OrderIdIsTooLong = "91501"
159
165
  PaymentMethodConflict = "91515"
160
166
  PaymentMethodDoesNotBelongToCustomer = "91516"
@@ -163,11 +169,15 @@ module Braintree
163
169
  PaymentMethodTokenIsInvalid = "91518"
164
170
  ProcessorAuthorizationCodeCannotBeSet = "91519"
165
171
  ProcessorAuthorizationCodeIsInvalid = "81520"
172
+ PurchaseOrderNumberIsTooLong = "91537"
166
173
  RefundAmountIsTooLarge = "91521"
167
174
  SettlementAmountIsTooLarge = "91522"
168
175
  SubscriptionDoesNotBelongToCustomer = "91529"
169
176
  SubscriptionIdIsInvalid = "91528"
170
177
  SubscriptionStatusMustBePastDue = "91531"
178
+ TaxAmountCannotBeNegative = "81534"
179
+ TaxAmountFormatIsInvalid = "81535"
180
+ TaxAmountIsTooLarge = "81536"
171
181
  TypeIsInvalid = "91523"
172
182
  TypeIsRequired = "91524"
173
183
  module Options
@@ -48,6 +48,7 @@ module Braintree
48
48
 
49
49
  def _http_do(http_verb, path, body = nil)
50
50
  connection = Net::HTTP.new(@config.server, @config.port)
51
+ connection.read_timeout = 60
51
52
  if @config.ssl?
52
53
  connection.use_ssl = true
53
54
  connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -27,6 +27,7 @@ module Braintree
27
27
  attr_reader :next_billing_period_amount
28
28
  attr_reader :number_of_billing_cycles, :billing_day_of_month
29
29
  attr_reader :add_ons, :discounts
30
+ attr_reader :descriptor
30
31
 
31
32
  # See http://www.braintreepaymentsolutions.com/docs/ruby/subscriptions/cancel
32
33
  def self.cancel(subscription_id)
@@ -70,6 +71,7 @@ module Braintree
70
71
  set_instance_variables_from_hash(attributes)
71
72
  @balance = Util.to_big_decimal(balance)
72
73
  @price = Util.to_big_decimal(price)
74
+ @descriptor = Descriptor.new(@descriptor)
73
75
  transactions.map! { |attrs| Transaction._new(gateway, attrs) }
74
76
  add_ons.map! { |attrs| AddOn._new(attrs) }
75
77
  discounts.map! { |attrs| Discount._new(attrs) }
@@ -64,7 +64,8 @@ module Braintree
64
64
  :trial_duration,
65
65
  :trial_duration_unit,
66
66
  :trial_period,
67
- {:options => [:do_not_inherit_add_ons_or_discounts, :start_immediately]}
67
+ {:options => [:do_not_inherit_add_ons_or_discounts, :start_immediately]},
68
+ {:descriptor => [:name, :phone]}
68
69
  ] + _add_on_discount_signature
69
70
  end
70
71
 
@@ -81,7 +82,8 @@ module Braintree
81
82
  :prorate_charges,
82
83
  :replace_all_add_ons_and_discounts,
83
84
  :revert_subscription_on_proration_failure
84
- ]}
85
+ ]},
86
+ {:descriptor => [:name, :phone]}
85
87
  ] + _add_on_discount_signature
86
88
  end
87
89
 
@@ -45,6 +45,7 @@ module Braintree
45
45
  attr_reader :currency_iso_code
46
46
  attr_reader :custom_fields
47
47
  attr_reader :cvv_response_code
48
+ attr_reader :descriptor
48
49
  attr_reader :gateway_rejection_reason
49
50
  attr_reader :merchant_account_id
50
51
  attr_reader :order_id
@@ -55,12 +56,15 @@ module Braintree
55
56
  attr_reader :processor_response_code
56
57
  # The response text from the processor.
57
58
  attr_reader :processor_response_text
59
+ attr_reader :purchase_order_number
58
60
  attr_reader :refund_ids, :refunded_transaction_id
59
61
  attr_reader :settlement_batch_id
60
62
  # See Transaction::Status
61
63
  attr_reader :status
62
64
  attr_reader :status_history
63
65
  attr_reader :subscription_id
66
+ attr_reader :tax_amount
67
+ attr_reader :tax_exempt
64
68
  # Will either be "sale" or "credit"
65
69
  attr_reader :type
66
70
  attr_reader :updated_at
@@ -154,6 +158,8 @@ module Braintree
154
158
  @billing_details = AddressDetails.new(@billing)
155
159
  @shipping_details = AddressDetails.new(@shipping)
156
160
  @status_history = attributes[:status_history] ? attributes[:status_history].map { |s| StatusDetails.new(s) } : []
161
+ @tax_amount = Util.to_big_decimal(tax_amount)
162
+ @descriptor = Descriptor.new(@descriptor)
157
163
  add_ons.map! { |attrs| AddOn._new(attrs) } if add_ons
158
164
  discounts.map! { |attrs| Discount._new(attrs) } if discounts
159
165
  end
@@ -89,7 +89,8 @@ module Braintree
89
89
 
90
90
  def self._create_signature # :nodoc:
91
91
  [
92
- :amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token, :shipping_address_id, :type,
92
+ :amount, :customer_id, :merchant_account_id, :order_id, :payment_method_token,
93
+ :purchase_order_number, :shipping_address_id, :type, :tax_amount, :tax_exempt,
93
94
  {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
94
95
  {:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
95
96
  {
@@ -99,7 +100,8 @@ module Braintree
99
100
  :shipping => AddressGateway._shared_signature
100
101
  },
101
102
  {:options => [:store_in_vault, :submit_for_settlement, :add_billing_address_to_payment_method, :store_shipping_address_in_vault]},
102
- {:custom_fields => :_any_key_}
103
+ {:custom_fields => :_any_key_},
104
+ {:descriptor => [:name, :phone]}
103
105
  ]
104
106
  end
105
107
 
@@ -1,8 +1,8 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 2
4
- Minor = 6
5
- Tiny = 3
4
+ Minor = 7
5
+ Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
8
8
  end
@@ -73,6 +73,17 @@ describe Braintree::CreditCard do
73
73
  credit_card.billing_address.last_name.should == "Tables"
74
74
  end
75
75
 
76
+ it "accepts empty options hash" do
77
+ customer = Braintree::Customer.create!
78
+ result = Braintree::CreditCard.create(
79
+ :customer_id => customer.id,
80
+ :number => Braintree::Test::CreditCardNumbers::FailsSandboxVerification::Visa,
81
+ :expiration_date => "05/2009",
82
+ :options => {}
83
+ )
84
+ result.success?.should == true
85
+ end
86
+
76
87
  it "verifies the credit card if options[verify_card]=true" do
77
88
  customer = Braintree::Customer.create!
78
89
  result = Braintree::CreditCard.create(
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::Transaction, "search" do
4
+ context "advanced" do
5
+ it "correctly returns a result with no matches" do
6
+ collection = Braintree::Customer.search do |search|
7
+ search.first_name.is "thisnameisnotreal"
8
+ end
9
+
10
+ collection.maximum_size.should == 0
11
+ end
12
+
13
+ it "can search on text fields" do
14
+ cctoken = "cctoken#{rand(1_000_000)}"
15
+ customer = Braintree::Customer.create!(
16
+ :first_name => "Timmy",
17
+ :last_name => "O'Toole",
18
+ :company => "O'Toole and #{rand(1_000_000)} Son(s)",
19
+ :email => "timmy@example.com",
20
+ :fax => "3145551234",
21
+ :phone => "5551231234",
22
+ :website => "http://example.com",
23
+ :credit_card => {
24
+ :cardholder_name => "Tim Tool",
25
+ :number => Braintree::Test::CreditCardNumbers::Visa,
26
+ :expiration_date => "05/2010",
27
+ :token => cctoken,
28
+ :billing_address => {
29
+ :first_name => "Thomas",
30
+ :last_name => "Otool",
31
+ :street_address => "1 E Main St",
32
+ :extended_address => "Suite 3",
33
+ :locality => "Chicago",
34
+ :region => "Illinois",
35
+ :postal_code => "60622",
36
+ :country_name => "United States of America"
37
+ }
38
+ }
39
+ )
40
+
41
+ customer = Braintree::Customer.find(customer.id)
42
+
43
+ search_criteria = {
44
+ :first_name => "Timmy",
45
+ :last_name => "O'Toole",
46
+ :company => customer.company,
47
+ :email => "timmy@example.com",
48
+ :phone => "5551231234",
49
+ :fax => "3145551234",
50
+ :website => "http://example.com",
51
+ :address_first_name => "Thomas",
52
+ :address_last_name => "Otool",
53
+ :address_street_address => "1 E Main St",
54
+ :address_postal_code => "60622",
55
+ :address_extended_address => "Suite 3",
56
+ :address_locality => "Chicago",
57
+ :address_region => "Illinois",
58
+ :payment_method_token => cctoken,
59
+ :cardholder_name => "Tim Tool",
60
+ :credit_card_expiration_date => "05/2010",
61
+ :credit_card_number => Braintree::Test::CreditCardNumbers::Visa
62
+ }
63
+
64
+ search_criteria.each do |criterion, value|
65
+ collection = Braintree::Customer.search do |search|
66
+ search.id.is customer.id
67
+ search.send(criterion).is value
68
+ end
69
+
70
+ collection.maximum_size.should == 1
71
+ collection.first.id.should == customer.id
72
+
73
+ collection = Braintree::Customer.search do |search|
74
+ search.id.is customer.id
75
+ search.send(criterion).is("invalid_attribute")
76
+ end
77
+ collection.should be_empty
78
+ end
79
+
80
+ collection = Braintree::Customer.search do |search|
81
+ search.id.is customer.id
82
+ search_criteria.each do |criterion, value|
83
+ search.send(criterion).is value
84
+ end
85
+ end
86
+
87
+ collection.maximum_size.should == 1
88
+ collection.first.id.should == customer.id
89
+ end
90
+
91
+ it "can search by created_at" do
92
+ company = "Company #{rand(1_000_000)}"
93
+ customer = Braintree::Customer.create!(
94
+ :company => company
95
+ )
96
+
97
+ created_at = customer.created_at
98
+ created_at.should be_utc
99
+
100
+ collection = Braintree::Customer.search do |search|
101
+ search.company.is company
102
+ search.created_at.between(
103
+ created_at - 60,
104
+ created_at + 60
105
+ )
106
+ end
107
+
108
+ collection.maximum_size.should == 1
109
+ collection.first.id.should == customer.id
110
+
111
+ collection = Braintree::Customer.search do |search|
112
+ search.company.is customer.company
113
+ search.created_at >= created_at - 1
114
+ end
115
+
116
+ collection.maximum_size.should == 1
117
+ collection.first.company.should == customer.company
118
+
119
+ collection = Braintree::Customer.search do |search|
120
+ search.company.is customer.company
121
+ search.created_at <= created_at + 1
122
+ end
123
+
124
+ collection.maximum_size.should == 1
125
+ collection.first.company.should == customer.company
126
+
127
+ collection = Braintree::Customer.search do |search|
128
+ search.company.is customer.company
129
+ search.created_at.between(
130
+ created_at - 300,
131
+ created_at - 100
132
+ )
133
+ end
134
+
135
+ collection.maximum_size.should == 0
136
+
137
+ collection = Braintree::Customer.search do |search|
138
+ search.company.is customer.company
139
+ search.created_at.is created_at
140
+ end
141
+
142
+ collection.maximum_size.should == 1
143
+ collection.first.company.should == customer.company
144
+ end
145
+ end
146
+ end
@@ -520,6 +520,42 @@ describe Braintree::Subscription do
520
520
  result.errors.for(:subscription).for(:add_ons).for(:update).for_index(1).on(:quantity)[0].code.should == Braintree::ErrorCodes::Subscription::Modification::QuantityIsInvalid
521
521
  end
522
522
  end
523
+
524
+ context "descriptors" do
525
+ it "accepts name and phone and copies them to the transaction" do
526
+ result = Braintree::Subscription.create(
527
+ :payment_method_token => @credit_card.token,
528
+ :plan_id => SpecHelper::TriallessPlan[:id],
529
+ :descriptor => {
530
+ :name => '123*123456789012345678',
531
+ :phone => '3334445555'
532
+ }
533
+ )
534
+
535
+ result.success?.should == true
536
+ result.subscription.descriptor.name.should == '123*123456789012345678'
537
+ result.subscription.descriptor.phone.should == '3334445555'
538
+
539
+ result.subscription.transactions.size.should == 1
540
+ transaction = result.subscription.transactions.first
541
+ transaction.descriptor.name.should == '123*123456789012345678'
542
+ transaction.descriptor.phone.should == '3334445555'
543
+ end
544
+
545
+ it "has validation errors if format is invalid" do
546
+ result = Braintree::Subscription.create(
547
+ :payment_method_token => @credit_card.token,
548
+ :plan_id => SpecHelper::TriallessPlan[:id],
549
+ :descriptor => {
550
+ :name => 'badcompanyname12*badproduct12',
551
+ :phone => '%bad4445555'
552
+ }
553
+ )
554
+ result.success?.should == false
555
+ result.errors.for(:subscription).for(:descriptor).on(:name)[0].code.should == Braintree::ErrorCodes::Descriptor::NameFormatIsInvalid
556
+ result.errors.for(:subscription).for(:descriptor).on(:phone)[0].code.should == Braintree::ErrorCodes::Descriptor::PhoneFormatIsInvalid
557
+ end
558
+ end
523
559
  end
524
560
 
525
561
  describe "self.create!" do
@@ -606,6 +642,19 @@ describe Braintree::Subscription do
606
642
  result.subscription.payment_method_token.should == new_credit_card.token
607
643
  end
608
644
 
645
+ it "allows chaning the descriptors" do
646
+ result = Braintree::Subscription.update(@subscription.id,
647
+ :descriptor => {
648
+ :name => 'aaa*1234',
649
+ :phone => '3334443333'
650
+ }
651
+ )
652
+
653
+ result.success?.should == true
654
+ result.subscription.descriptor.name.should == 'aaa*1234'
655
+ result.subscription.descriptor.phone.should == '3334443333'
656
+ end
657
+
609
658
  context "when successful" do
610
659
  it "returns a success response with the updated subscription if valid" do
611
660
  new_id = rand(36**9).to_s(36)
@@ -10,7 +10,7 @@ describe Braintree::Transaction, "search" do
10
10
  collection.maximum_size.should == 0
11
11
  end
12
12
 
13
- it "returns one result for text field search" do
13
+ it "can search on text fields" do
14
14
  first_name = "Tim#{rand(10000)}"
15
15
  token = "creditcard#{rand(10000)}"
16
16
  customer_id = "customer#{rand(10000)}"
@@ -115,92 +115,12 @@ describe Braintree::Transaction, "search" do
115
115
  end
116
116
  collection.should be_empty
117
117
  end
118
- end
119
-
120
- it "searches all fields at once" do
121
- first_name = "Tim#{rand(10000)}"
122
- token = "creditcard#{rand(10000)}"
123
- customer_id = "customer#{rand(10000)}"
124
-
125
- transaction = Braintree::Transaction.sale!(
126
- :amount => Braintree::Test::TransactionAmounts::Authorize,
127
- :credit_card => {
128
- :number => Braintree::Test::CreditCardNumbers::Visa,
129
- :expiration_date => "05/2012",
130
- :cardholder_name => "Tom Smith",
131
- :token => token,
132
- },
133
- :billing => {
134
- :company => "Braintree",
135
- :country_name => "United States of America",
136
- :extended_address => "Suite 123",
137
- :first_name => first_name,
138
- :last_name => "Smith",
139
- :locality => "Chicago",
140
- :postal_code => "12345",
141
- :region => "IL",
142
- :street_address => "123 Main St"
143
- },
144
- :customer => {
145
- :company => "Braintree",
146
- :email => "smith@example.com",
147
- :fax => "5551231234",
148
- :first_name => "Tom",
149
- :id => customer_id,
150
- :last_name => "Smith",
151
- :phone => "5551231234",
152
- :website => "http://example.com",
153
- },
154
- :options => {
155
- :store_in_vault => true
156
- },
157
- :order_id => "myorder",
158
- :shipping => {
159
- :company => "Braintree P.S.",
160
- :country_name => "Mexico",
161
- :extended_address => "Apt 456",
162
- :first_name => "Thomas",
163
- :last_name => "Smithy",
164
- :locality => "Braintree",
165
- :postal_code => "54321",
166
- :region => "MA",
167
- :street_address => "456 Road"
168
- })
169
118
 
170
119
  collection = Braintree::Transaction.search do |search|
171
- search.billing_company.is "Braintree"
172
- search.billing_country_name.is "United States of America"
173
- search.billing_extended_address.is "Suite 123"
174
- search.billing_first_name.is first_name
175
- search.billing_last_name.is "Smith"
176
- search.billing_locality.is "Chicago"
177
- search.billing_postal_code.is "12345"
178
- search.billing_region.is "IL"
179
- search.billing_street_address.is "123 Main St"
180
- search.credit_card_cardholder_name.is "Tom Smith"
181
- search.credit_card_expiration_date.is "05/2012"
182
- search.credit_card_number.is Braintree::Test::CreditCardNumbers::Visa
183
- search.customer_company.is "Braintree"
184
- search.customer_email.is "smith@example.com"
185
- search.customer_fax.is "5551231234"
186
- search.customer_first_name.is "Tom"
187
- search.customer_id.is customer_id
188
- search.customer_last_name.is "Smith"
189
- search.customer_phone.is "5551231234"
190
- search.customer_website.is "http://example.com"
191
- search.order_id.is "myorder"
192
- search.payment_method_token.is token
193
- search.processor_authorization_code.is transaction.processor_authorization_code
194
- search.shipping_company.is "Braintree P.S."
195
- search.shipping_country_name.is "Mexico"
196
- search.shipping_extended_address.is "Apt 456"
197
- search.shipping_first_name.is "Thomas"
198
- search.shipping_last_name.is "Smithy"
199
- search.shipping_locality.is "Braintree"
200
- search.shipping_postal_code.is "54321"
201
- search.shipping_region.is "MA"
202
- search.shipping_street_address.is "456 Road"
203
120
  search.id.is transaction.id
121
+ search_criteria.each do |criterion, value|
122
+ search.send(criterion).is value
123
+ end
204
124
  end
205
125
 
206
126
  collection.maximum_size.should == 1
@@ -518,9 +438,9 @@ describe Braintree::Transaction, "search" do
518
438
  transaction = Braintree::Transaction.sale!(
519
439
  :amount => Braintree::Test::TransactionAmounts::Authorize,
520
440
  :credit_card => {
521
- :number => Braintree::Test::CreditCardNumbers::Visa,
522
- :expiration_date => "05/12"
523
- }
441
+ :number => Braintree::Test::CreditCardNumbers::Visa,
442
+ :expiration_date => "05/12"
443
+ }
524
444
  )
525
445
 
526
446
  created_at = transaction.created_at
@@ -512,6 +512,92 @@ describe Braintree::Transaction do
512
512
  transaction.discounts.first.number_of_billing_cycles.should be_nil
513
513
  transaction.discounts.first.never_expires?.should be_true
514
514
  end
515
+
516
+ context "descriptors" do
517
+ it "accepts name and phone" do
518
+ result = Braintree::Transaction.sale(
519
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
520
+ :credit_card => {
521
+ :number => Braintree::Test::CreditCardNumbers::Visa,
522
+ :expiration_date => "05/2009"
523
+ },
524
+ :descriptor => {
525
+ :name => '123*123456789012345678',
526
+ :phone => '3334445555'
527
+ }
528
+ )
529
+ result.success?.should == true
530
+ result.transaction.descriptor.name.should == '123*123456789012345678'
531
+ result.transaction.descriptor.phone.should == '3334445555'
532
+ end
533
+
534
+ it "has validation errors if format is invalid" do
535
+ result = Braintree::Transaction.sale(
536
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
537
+ :credit_card => {
538
+ :number => Braintree::Test::CreditCardNumbers::Visa,
539
+ :expiration_date => "05/2009"
540
+ },
541
+ :descriptor => {
542
+ :name => 'badcompanyname12*badproduct12',
543
+ :phone => '%bad4445555'
544
+ }
545
+ )
546
+ result.success?.should == false
547
+ result.errors.for(:transaction).for(:descriptor).on(:name)[0].code.should == Braintree::ErrorCodes::Descriptor::NameFormatIsInvalid
548
+ result.errors.for(:transaction).for(:descriptor).on(:phone)[0].code.should == Braintree::ErrorCodes::Descriptor::PhoneFormatIsInvalid
549
+ end
550
+ end
551
+
552
+ context "level 2 fields" do
553
+ it "accepts tax_amount, tax_exempt, and purchase_order_number" do
554
+ result = Braintree::Transaction.sale(
555
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
556
+ :credit_card => {
557
+ :number => Braintree::Test::CreditCardNumbers::Visa,
558
+ :expiration_date => "05/2009"
559
+ },
560
+ :tax_amount => '0.05',
561
+ :tax_exempt => false,
562
+ :purchase_order_number => '12345678901234567'
563
+ )
564
+ result.success?.should == true
565
+ result.transaction.tax_amount.should == BigDecimal.new("0.05")
566
+ result.transaction.tax_exempt.should == false
567
+ result.transaction.purchase_order_number.should == '12345678901234567'
568
+ end
569
+
570
+ it "accepts tax_amount as a BigDecimal" do
571
+ result = Braintree::Transaction.sale(
572
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
573
+ :credit_card => {
574
+ :number => Braintree::Test::CreditCardNumbers::Visa,
575
+ :expiration_date => "05/2009"
576
+ },
577
+ :tax_amount => BigDecimal.new('1.99'),
578
+ :tax_exempt => true
579
+ )
580
+ result.success?.should == true
581
+ result.transaction.tax_amount.should == BigDecimal.new("1.99")
582
+ result.transaction.tax_exempt.should == true
583
+ result.transaction.purchase_order_number.should be_nil
584
+ end
585
+
586
+ it "has validation errors" do
587
+ result = Braintree::Transaction.sale(
588
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
589
+ :credit_card => {
590
+ :number => Braintree::Test::CreditCardNumbers::Visa,
591
+ :expiration_date => "05/2009"
592
+ },
593
+ :tax_amount => 'abcd',
594
+ :purchase_order_number => 'a' * 18
595
+ )
596
+ result.success?.should == false
597
+ result.errors.for(:transaction).on(:tax_amount)[0].code.should == Braintree::ErrorCodes::Transaction::TaxAmountFormatIsInvalid
598
+ result.errors.for(:transaction).on(:purchase_order_number)[0].code.should == Braintree::ErrorCodes::Transaction::PurchaseOrderNumberIsTooLong
599
+ end
600
+ end
515
601
  end
516
602
 
517
603
  describe "self.create!" do
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: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
- - 6
9
- - 3
10
- version: 2.6.3
8
+ - 7
9
+ - 0
10
+ version: 2.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Braintree Payment Solutions
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-10 00:00:00 -06:00
18
+ date: 2011-01-26 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -55,6 +55,8 @@ files:
55
55
  - lib/braintree/credit_card_verification.rb
56
56
  - lib/braintree/customer.rb
57
57
  - lib/braintree/customer_gateway.rb
58
+ - lib/braintree/customer_search.rb
59
+ - lib/braintree/descriptor.rb
58
60
  - lib/braintree/digest.rb
59
61
  - lib/braintree/discount.rb
60
62
  - lib/braintree/error_codes.rb
@@ -94,6 +96,7 @@ files:
94
96
  - spec/integration/braintree/address_spec.rb
95
97
  - spec/integration/braintree/advanced_search_spec.rb
96
98
  - spec/integration/braintree/credit_card_spec.rb
99
+ - spec/integration/braintree/customer_search_spec.rb
97
100
  - spec/integration/braintree/customer_spec.rb
98
101
  - spec/integration/braintree/error_codes_spec.rb
99
102
  - spec/integration/braintree/http_spec.rb