braintree 3.4.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 85d22ee560b343f4bbd3f71272f4e9d5cfaa83672ddc36fceb9fc383b25772e3
4
- data.tar.gz: 8d29ee6fcd9b7f6ccbab6680029b66c70e53867448b369af806feb454cfdb18c
3
+ metadata.gz: a48854f74d17f7c0f06f437ab9cf144f6787cdb634cb4585b96cbf0e8b3eb316
4
+ data.tar.gz: e278599e9a4fe1ec55ed4c25a0c2941c256815adff6240f24d7326dda3c7979b
5
5
  SHA512:
6
- metadata.gz: d35fdc8ebf0d555649b08e401b4b16f6ac58ee52ca3fdb6a0ce899b10a4c7b2db94873fdb940649941c105cf9ca44686a415a9760619be4e7f5d7d9b33883e81
7
- data.tar.gz: 687c698cd56953bc23694112256bfe422b53e0a0f0697e5c6626567933ecaab332a1fc6732f4085747ef68178a1d76d6f76a372ec070feb365c8557db8301f51
6
+ metadata.gz: dbe42e3ee49bffddde129c228d9dc9ea9a8e7615140d184211378d58add503f13a666f2aaf8c393fafbb330db77685a5953b10344c712da5719c630f1ab64e5a
7
+ data.tar.gz: ae8af00364f7853fb0e6eb82f585ebc30015f0b6ac7014f41eccdfe732348f3b3f715b474afc516b17b913550f9ae339b587a53296cc823bb30c5954ecbda146
data/braintree.gemspec CHANGED
@@ -12,8 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.homepage = "https://www.braintreepayments.com/"
13
13
  s.files = Dir.glob ["README.rdoc", "LICENSE", "lib/**/*.{rb,crt}", "spec/**/*", "*.gemspec"]
14
14
  s.add_dependency "builder", ">= 3.2.4"
15
- s.add_dependency "libxml-ruby", ">= 3.2.0"
16
- s.required_ruby_version = ">=2.5.0"
15
+ s.required_ruby_version = ">=2.6.0"
17
16
  s.metadata = {
18
17
  "bug_tracker_uri" => "https://github.com/braintree/braintree_ruby/issues",
19
18
  "changelog_uri" => "https://github.com/braintree/braintree_ruby/blob/master/CHANGELOG.md",
data/lib/braintree.rb CHANGED
@@ -59,6 +59,7 @@ require "braintree/discount_gateway"
59
59
  require "braintree/dispute"
60
60
  require "braintree/dispute_gateway"
61
61
  require "braintree/dispute/evidence"
62
+ require "braintree/dispute/paypal_message"
62
63
  require "braintree/dispute/status_history"
63
64
  require "braintree/dispute/transaction"
64
65
  require "braintree/dispute/transaction_details"
@@ -87,6 +88,8 @@ require "braintree/payment_instrument_type"
87
88
  require "braintree/payment_method"
88
89
  require "braintree/payment_method_gateway"
89
90
  require "braintree/payment_method_nonce"
91
+ require "braintree/payment_method_nonce_details"
92
+ require "braintree/payment_method_nonce_details_payer_info"
90
93
  require "braintree/payment_method_nonce_gateway"
91
94
  require "braintree/payment_method_parser"
92
95
  require "braintree/paypal_account"
@@ -160,4 +163,5 @@ require "braintree/webhook_testing_gateway"
160
163
  require "braintree/xml"
161
164
  require "braintree/xml/generator"
162
165
  require "braintree/xml/libxml"
166
+ require "braintree/xml/rexml"
163
167
  require "braintree/xml/parser"
@@ -14,6 +14,7 @@ module Braintree
14
14
  attr_reader :id
15
15
  attr_reader :last_name
16
16
  attr_reader :locality
17
+ attr_reader :phone_number
17
18
  attr_reader :postal_code
18
19
  attr_reader :region
19
20
  attr_reader :street_address
@@ -19,6 +19,7 @@ module Braintree
19
19
  attr_reader :paypal_accounts
20
20
  attr_reader :phone
21
21
  attr_reader :samsung_pay_cards
22
+ attr_reader :tax_identifiers
22
23
  attr_reader :updated_at
23
24
  attr_reader :us_bank_accounts
24
25
  attr_reader :venmo_accounts
@@ -90,6 +91,7 @@ module Braintree
90
91
  @visa_checkout_cards = (@visa_checkout_cards|| []).map { |pm| VisaCheckoutCard._new gateway, pm }
91
92
  @samsung_pay_cards = (@samsung_pay_cards|| []).map { |pm| SamsungPayCard._new gateway, pm }
92
93
  @addresses = (@addresses || []).map { |addr| Address._new gateway, addr }
94
+ @tax_identifiers = (@tax_identifiers || []).map { |addr| TaxIdentifier._new gateway, addr }
93
95
  @custom_fields = attributes[:custom_fields].is_a?(Hash) ? attributes[:custom_fields] : {}
94
96
  end
95
97
 
@@ -124,7 +126,7 @@ module Braintree
124
126
 
125
127
  def inspect # :nodoc:
126
128
  first = [:id]
127
- last = [:addresses, :credit_cards, :paypal_accounts]
129
+ last = [:addresses, :credit_cards, :paypal_accounts, :tax_identifiers]
128
130
  order = first + (self.class._attributes - first - last) + last
129
131
  nice_attributes = order.map do |attr|
130
132
  "#{attr}: #{send(attr).inspect}"
@@ -148,7 +150,7 @@ module Braintree
148
150
  def self._attributes # :nodoc:
149
151
  [
150
152
  :addresses, :company, :credit_cards, :email, :fax, :first_name, :id, :last_name, :phone, :website,
151
- :created_at, :updated_at
153
+ :created_at, :updated_at, :tax_identifiers
152
154
  ]
153
155
  end
154
156
 
@@ -80,6 +80,7 @@ module Braintree
80
80
  {:risk_data => [:customer_browser, :customer_ip]},
81
81
  {:credit_card => credit_card_signature},
82
82
  {:paypal_account => paypal_account_signature},
83
+ {:tax_identifiers => [:country_code, :identifier]},
83
84
  {:options => options},
84
85
  {:custom_fields => :_any_key_}
85
86
  ]
@@ -141,6 +142,7 @@ module Braintree
141
142
  :company, :email, :fax, :first_name, :id, :last_name, :phone, :website,
142
143
  :device_data, :payment_method_nonce, :default_payment_method_token,
143
144
  {:credit_card => credit_card_signature},
145
+ {:tax_identifiers => [:country_code, :identifier]},
144
146
  {:options => options},
145
147
  {:custom_fields => :_any_key_}
146
148
  ]
@@ -7,6 +7,7 @@ module Braintree
7
7
  attr_reader :amount_disputed
8
8
  attr_reader :amount_won
9
9
  attr_reader :case_number
10
+ attr_reader :chargeback_protection_level
10
11
  attr_reader :created_at
11
12
  attr_reader :currency_iso_code
12
13
  attr_reader :date_opened
@@ -17,6 +18,7 @@ module Braintree
17
18
  attr_reader :kind
18
19
  attr_reader :merchant_account_id
19
20
  attr_reader :original_dispute_id
21
+ attr_reader :paypal_messages
20
22
  attr_reader :processor_comments
21
23
  attr_reader :reason
22
24
  attr_reader :reason_code
@@ -65,6 +67,14 @@ module Braintree
65
67
  All = constants.map { |c| const_get(c) }
66
68
  end
67
69
 
70
+ module ChargebackProtectionLevel
71
+ Effortless = "effortless"
72
+ Standard = "standard"
73
+ NotProtected = "not_protected"
74
+
75
+ All = constants.map { |c| const_get(c) }
76
+ end
77
+
68
78
  class << self
69
79
  protected :new
70
80
  def _new(*args) # :nodoc:
@@ -114,6 +124,10 @@ module Braintree
114
124
  Braintree::Dispute::Evidence.new(record)
115
125
  end unless evidence.nil?
116
126
 
127
+ @paypal_messages = paypal_messages.map do |record|
128
+ Braintree::Dispute::PayPalMessage.new(record)
129
+ end unless paypal_messages.nil?
130
+
117
131
  @transaction_details = TransactionDetails.new(transaction)
118
132
  @transaction = Transaction.new(transaction)
119
133
 
@@ -0,0 +1,15 @@
1
+ module Braintree
2
+ class Dispute
3
+ class PayPalMessage # :nodoc:
4
+ include BaseModule
5
+
6
+ attr_reader :message,
7
+ :sender,
8
+ :sent_at
9
+
10
+ def initialize(attributes)
11
+ set_instance_variables_from_hash attributes unless attributes.nil?
12
+ end
13
+ end
14
+ end
15
+ end
@@ -8,6 +8,7 @@ module Braintree
8
8
  :transaction_id,
9
9
  )
10
10
 
11
+ multiple_value_field :chargeback_protection_level, :allows => Dispute::ChargebackProtectionLevel::All
11
12
  multiple_value_field :kind, :allows => Dispute::Kind::All
12
13
  multiple_value_field :merchant_account_id
13
14
  multiple_value_field :reason, :allows => Dispute::Reason::All
@@ -517,8 +517,6 @@ module Braintree
517
517
  end
518
518
 
519
519
  module ExternalVault
520
- # NEXT_MAJOR_VERSION remove this validation error as it is no longer returned by the gateway
521
- CardTypeIsInvalid = "915178"
522
520
  PreviousNetworkTransactionIdIsInvalid = "915179"
523
521
  StatusIsInvalid = "915175"
524
522
  StatusWithPreviousNetworkTransactionIdIsInvalid = "915177"
@@ -786,8 +784,6 @@ module Braintree
786
784
  end
787
785
 
788
786
  module RiskData
789
- # NEXT_MAJOR_VERSION Remove CustomerBrowserIsTooLong (this validation is no longer applied)
790
- CustomerBrowserIsTooLong = "94701"
791
787
  CustomerDeviceIdIsTooLong = "94702"
792
788
  CustomerLocationZipInvalidCharacters = "94703"
793
789
  CustomerLocationZipIsInvalid = "94704"
@@ -186,8 +186,6 @@ module Braintree
186
186
  options << :fail_on_duplicate_payment_method
187
187
  signature << :customer_id
188
188
  signature << :paypal_refresh_token
189
- # NEXT_MAJOR_VERSION remove this from the signature
190
- signature << :paypal_vault_without_upgrade
191
189
  when :update
192
190
  billing_address_params << {:options => [:update_existing]}
193
191
  else
@@ -25,7 +25,7 @@ module Braintree
25
25
  @gateway = gateway
26
26
  @nonce = attributes.fetch(:nonce)
27
27
  @type = attributes.fetch(:type)
28
- @details = attributes.fetch(:details)
28
+ @details = PaymentMethodNonceDetails.new(attributes[:details]) if attributes[:details]
29
29
  @authentication_insight = attributes.fetch(:authentication_insight, nil)
30
30
  @three_d_secure_info = ThreeDSecureInfo.new(attributes[:three_d_secure_info]) if attributes[:three_d_secure_info]
31
31
  @bin_data = BinData.new(attributes[:bin_data]) if attributes[:bin_data]
@@ -0,0 +1,37 @@
1
+ module Braintree
2
+ class PaymentMethodNonceDetails # :nodoc:
3
+ include BaseModule
4
+
5
+ attr_reader :bin
6
+ attr_reader :card_type
7
+ attr_reader :expiration_month
8
+ attr_reader :expiration_year
9
+ attr_reader :is_network_tokenized
10
+ attr_reader :last_two
11
+ attr_reader :payer_info
12
+
13
+ alias_method :is_network_tokenized?, :is_network_tokenized
14
+
15
+ def initialize(attributes)
16
+ set_instance_variables_from_hash attributes unless attributes.nil?
17
+ @payer_info = PaymentMethodNonceDetailsPayerInfo.new(attributes[:payer_info]) if attributes[:payer_info]
18
+ end
19
+
20
+ def inspect
21
+ attr_order = [
22
+ :bin,
23
+ :card_type,
24
+ :expiration_month,
25
+ :expiration_year,
26
+ :is_network_tokenized,
27
+ :last_two,
28
+ :payer_info,
29
+ ]
30
+
31
+ formatted_attrs = attr_order.map do |attr|
32
+ "#{attr}: #{send(attr).inspect}"
33
+ end
34
+ "#<PaymentMethodNonceDetails #{formatted_attrs.join(", ")}>"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ module Braintree
2
+ class PaymentMethodNonceDetailsPayerInfo # :nodoc:
3
+ include BaseModule
4
+
5
+ attr_reader :billing_agreement_id
6
+ attr_reader :country_code
7
+ attr_reader :email
8
+ attr_reader :first_name
9
+ attr_reader :last_name
10
+ attr_reader :payer_id
11
+
12
+ def initialize(attributes)
13
+ set_instance_variables_from_hash attributes unless attributes.nil?
14
+ end
15
+
16
+ def inspect
17
+ attr_order = [
18
+ :billing_agreement_id,
19
+ :country_code,
20
+ :email,
21
+ :first_name,
22
+ :last_name,
23
+ :payer_id,
24
+ ]
25
+
26
+ formatted_attrs = attr_order.map do |attr|
27
+ "#{attr}: #{send(attr).inspect}"
28
+ end
29
+ "#<PaymentMethodNonceDetailsPayerInfo #{formatted_attrs.join(", ")}>"
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
- Major = 3
4
- Minor = 4
3
+ Major = 4
4
+ Minor = 0
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
@@ -1,4 +1,3 @@
1
- require "libxml"
2
1
  # Portions of this code were copied and modified from Ruby on Rails, released
3
2
  # under the MIT license, copyright (c) 2005-2009 David Heinemeier Hansson
4
3
  module Braintree
@@ -11,12 +11,22 @@ module Braintree
11
11
  "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
12
12
  }
13
13
 
14
- def self.hash_from_xml(xml)
15
- standardized_hash_structure = ::Braintree::Xml::Libxml.parse(xml)
14
+ def self.hash_from_xml(xml, parser = _determine_parser)
15
+ standardized_hash_structure = parser.parse(xml)
16
16
  transformed_xml = _transform_xml(standardized_hash_structure)
17
17
  Util.symbolize_keys(transformed_xml)
18
18
  end
19
19
 
20
+ def self._determine_parser
21
+ # If LibXML is not available, we fall back to REXML
22
+ # This allows us to be compatible with JRuby, which LibXML does not support
23
+ if defined?(::LibXML::XML) && ::LibXML::XML.respond_to?(:default_keep_blanks=)
24
+ ::Braintree::Xml::Libxml
25
+ else
26
+ ::Braintree::Xml::Rexml
27
+ end
28
+ end
29
+
20
30
  # Transform into standard Ruby types and convert all keys to snake_case instead of dash-case
21
31
  def self._transform_xml(value)
22
32
  case value.class.to_s
@@ -0,0 +1,70 @@
1
+ # Portions of this code were copied and modified from Ruby on Rails, released
2
+ # under the MIT license, copyright (c) 2005-2009 David Heinemeier Hansson
3
+ module Braintree
4
+ module Xml # :nodoc:
5
+ module Rexml # :nodoc:
6
+
7
+ CONTENT_KEY = "__content__".freeze
8
+
9
+ def self.parse(string)
10
+ require "rexml/document" unless defined?(REXML::Document)
11
+ doc = REXML::Document.new(string)
12
+ _merge_element!({}, doc.root)
13
+ end
14
+
15
+ def self._merge_element!(hash, element)
16
+ _merge!(hash, element.name, _collapse(element))
17
+ end
18
+
19
+ def self._collapse(element)
20
+ hash = _get_attributes(element)
21
+
22
+ if element.has_elements?
23
+ element.each_element { |child| _merge_element!(hash, child) }
24
+ _merge_texts!(hash, element) unless _empty_content?(element)
25
+ hash
26
+ else
27
+ _merge_texts!(hash, element)
28
+ end
29
+ end
30
+
31
+ def self._merge_texts!(hash, element)
32
+ unless element.has_text?
33
+ hash
34
+ else
35
+ # must use value to prevent double-escaping
36
+ _merge!(
37
+ hash,
38
+ CONTENT_KEY,
39
+ element.texts.map { |t| t.value }.join,
40
+ )
41
+ end
42
+ end
43
+
44
+ def self._merge!(hash, key, value)
45
+ if hash.has_key?(key)
46
+ if hash[key].instance_of?(Array)
47
+ hash[key] << value
48
+ else
49
+ hash[key] = [hash[key], value]
50
+ end
51
+ elsif value.instance_of?(Array)
52
+ hash[key] = [value]
53
+ else
54
+ hash[key] = value
55
+ end
56
+ hash
57
+ end
58
+
59
+ def self._get_attributes(element)
60
+ attributes = {}
61
+ element.attributes.each { |n,v| attributes[n] = v }
62
+ attributes
63
+ end
64
+
65
+ def self._empty_content?(element)
66
+ element.texts.join.strip == ""
67
+ end
68
+ end
69
+ end
70
+ end
@@ -14,6 +14,7 @@ describe Braintree::Address do
14
14
  :extended_address => "Suite 200",
15
15
  :locality => "Chicago",
16
16
  :region => "Illinois",
17
+ :phone_number => "5551231234",
17
18
  :postal_code => "60622",
18
19
  :country_name => "United States of America",
19
20
  )
@@ -26,6 +27,7 @@ describe Braintree::Address do
26
27
  result.address.extended_address.should == "Suite 200"
27
28
  result.address.locality.should == "Chicago"
28
29
  result.address.region.should == "Illinois"
30
+ result.address.phone_number.should == "5551231234"
29
31
  result.address.postal_code.should == "60622"
30
32
  result.address.country_name.should == "United States of America"
31
33
  result.address.country_code_alpha2.should == "US"
@@ -131,6 +133,7 @@ describe Braintree::Address do
131
133
  :extended_address => "Suite 201",
132
134
  :locality => "Bartlett",
133
135
  :region => "IL",
136
+ :phone_number => "5551231234",
134
137
  :postal_code => "60623",
135
138
  :country_name => "United States of America",
136
139
  )
@@ -139,6 +142,7 @@ describe Braintree::Address do
139
142
  address.extended_address.should == "Suite 201"
140
143
  address.locality.should == "Bartlett"
141
144
  address.region.should == "IL"
145
+ address.phone_number.should == "5551231234"
142
146
  address.postal_code.should == "60623"
143
147
  address.country_name.should == "United States of America"
144
148
  end
@@ -40,6 +40,7 @@ describe Braintree::Customer do
40
40
  :phone => "312.555.1234",
41
41
  :fax => "614.555.5678",
42
42
  :website => "www.microsoft.com",
43
+ :tax_identifiers => [{:country_code => "US", :identifier => "987654321"}],
43
44
  )
44
45
  result.success?.should == true
45
46
  result.customer.id.should =~ /^\d{6,}$/
@@ -114,6 +115,17 @@ describe Braintree::Customer do
114
115
  result.should be_success
115
116
  end
116
117
 
118
+ it "supports creation with tax_identifiers" do
119
+ result = Braintree::Customer.create(
120
+ :tax_identifiers => [
121
+ {:country_code => "US", :identifier => "987654321"},
122
+ {:country_code => "CL", :identifier => "123456789"}
123
+ ],
124
+ )
125
+
126
+ result.should be_success
127
+ end
128
+
117
129
  it "can create without any attributes" do
118
130
  result = Braintree::Customer.create
119
131
  result.success?.should == true
@@ -1333,6 +1345,21 @@ describe Braintree::Customer do
1333
1345
  result.success?.should == true
1334
1346
  end
1335
1347
 
1348
+ it "can update a tax_identifier" do
1349
+ customer = Braintree::Customer.create!(
1350
+ :tax_identifiers => [
1351
+ {:country_code => "US", :identifier => "987654321"},
1352
+ {:country_code => "CL", :identifier => "123456789"}
1353
+ ],
1354
+ )
1355
+
1356
+ result = Braintree::Customer.update(
1357
+ customer.id,
1358
+ :tax_identifiers => [{:country_code => "US", :identifier => "567891234"}],
1359
+ )
1360
+ result.success?.should == true
1361
+ end
1362
+
1336
1363
  it "validates presence of three_d_secure_version in 3ds pass thru params" do
1337
1364
  result = Braintree::Customer.create(
1338
1365
  :payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
@@ -78,6 +78,31 @@ describe Braintree::Dispute, "search" do
78
78
  dispute = collection.disputes.first
79
79
  end
80
80
 
81
+ it "correctly returns chargeback protected disputes" do
82
+ collection = Braintree::Dispute.search do |search|
83
+ search.case_number.is "CASE-CHARGEBACK-PROTECTED"
84
+ end
85
+
86
+ expect(collection.disputes.count).to eq(1)
87
+ dispute = collection.disputes.first
88
+
89
+ expect(dispute.chargeback_protection_level).to eq(Braintree::Dispute::ChargebackProtectionLevel::Effortless)
90
+ expect(dispute.reason).to eq(Braintree::Dispute::Reason::Fraud)
91
+ end
92
+
93
+ it "correctly returns disputes by chargeback protection level flag" do
94
+ collection = Braintree::Dispute.search do |search|
95
+ search.chargeback_protection_level.in [
96
+ Braintree::Dispute::ChargebackProtectionLevel::Effortless
97
+ ]
98
+ end
99
+ expect(collection.disputes.count).to eq(1)
100
+ dispute = collection.disputes.first
101
+
102
+ expect(dispute.chargeback_protection_level).to eq(Braintree::Dispute::ChargebackProtectionLevel::Effortless)
103
+ expect(dispute.reason).to eq(Braintree::Dispute::Reason::Fraud)
104
+ end
105
+
81
106
  it "correctly returns disputes by effective_date range" do
82
107
  effective_date = transaction.disputes.first.status_history.first.effective_date
83
108
 
@@ -79,33 +79,24 @@ describe Braintree::PaymentMethodNonce do
79
79
  result.should be_success
80
80
  nonce.nonce.should == "fake-valid-nonce"
81
81
  nonce.type.should == "CreditCard"
82
- nonce.details.fetch(:last_two).should == "81"
83
- nonce.details.fetch(:card_type).should == "Visa"
82
+ nonce.details.bin.should == "401288"
83
+ nonce.details.card_type.should == "Visa"
84
+ nonce.details.expiration_month.should == "12"
85
+ nonce.details.expiration_year.should == "2022"
86
+ nonce.details.is_network_tokenized?.should be_nil
87
+ nonce.details.last_two.should == "81"
88
+ nonce.details.payer_info.should be_nil
84
89
  end
85
90
 
86
91
  it "return paypal details if details exist" do
87
92
  result = Braintree::PaymentMethodNonce.find("fake-paypal-one-time-nonce")
88
93
  nonce = result.payment_method_nonce
89
-
90
- nonce.details.fetch(:cobranded_card_label).should_not be_nil
91
- nonce.details.fetch(:shipping_option_id).should_not be_nil
92
- nonce.details.fetch(:billing_address).fetch(:recipient_name).should_not be_nil
93
- nonce.details.fetch(:shipping_address).fetch(:recipient_name).should_not be_nil
94
-
95
- nonce.details.fetch(:payer_info).fetch(:first_name).should_not be_nil
96
- nonce.details.fetch(:payer_info).fetch(:last_name).should_not be_nil
97
- nonce.details.fetch(:payer_info).fetch(:email).should_not be_nil
98
- nonce.details.fetch(:payer_info).fetch(:payer_id).should_not be_nil
99
- end
100
-
101
- it "return venmo details if details exist" do
102
- result = Braintree::PaymentMethodNonce.find("fake-venmo-account-nonce")
103
-
104
- nonce = result.payment_method_nonce
105
-
106
- nonce.details.fetch(:last_two).should == "99"
107
- nonce.details.fetch(:username).should == "venmojoe"
108
- nonce.details.fetch(:venmo_user_id).should == "Venmo-Joe-1"
94
+ nonce.details.payer_info.billing_agreement_id.should be_nil
95
+ nonce.details.payer_info.country_code.should be_nil
96
+ nonce.details.payer_info.email.should_not be_nil
97
+ nonce.details.payer_info.first_name.should_not be_nil
98
+ nonce.details.payer_info.last_name.should_not be_nil
99
+ nonce.details.payer_info.payer_id.should_not be_nil
109
100
  end
110
101
 
111
102
  it "returns null 3ds_info if there isn't any" do
@@ -131,7 +122,7 @@ describe Braintree::PaymentMethodNonce do
131
122
  nonce = result.payment_method_nonce
132
123
  result.should be_success
133
124
  nonce.details.should_not be_nil
134
- nonce.details[:bin].should == "401288"
125
+ nonce.details.bin.should == "401288"
135
126
  end
136
127
 
137
128
  it "returns bin_data with commercial set to Yes" do
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ unless defined?(SPEC_HELPER_LOADED)
3
3
  project_root = File.expand_path(File.dirname(__FILE__) + "/..")
4
4
  require "rubygems"
5
5
  require "bundler/setup"
6
+ require "libxml"
6
7
  require "rspec"
7
8
  require "pry"
8
9
 
@@ -31,6 +31,7 @@ describe Braintree::Customer do
31
31
  output.should include(%q(addresses: []))
32
32
  output.should include(%q(credit_cards: []))
33
33
  output.should include(%q(paypal_accounts: []))
34
+ output.should include(%q(tax_identifiers: []))
34
35
  output.should include(%Q(created_at: #{customer.created_at.inspect}))
35
36
  output.should include(%Q(updated_at: #{customer.updated_at.inspect}))
36
37
  end
@@ -133,6 +134,10 @@ describe Braintree::Customer do
133
134
  :billing_agreement_id,
134
135
  {:options => [:make_default]},
135
136
  ]},
137
+ {:tax_identifiers => [
138
+ :country_code,
139
+ :identifier
140
+ ]},
136
141
  {:options =>
137
142
  [:paypal => [
138
143
  :payee_email,
@@ -227,6 +232,10 @@ describe Braintree::Customer do
227
232
  :ds_transaction_id,
228
233
  ]},
229
234
  ]},
235
+ {:tax_identifiers => [
236
+ :country_code,
237
+ :identifier
238
+ ]},
230
239
  {:options =>
231
240
  [:paypal => [
232
241
  :payee_email,
@@ -41,6 +41,7 @@ describe Braintree::DisputeSearch do
41
41
  end
42
42
 
43
43
  [
44
+ :chargeback_protection_level,
44
45
  :kind,
45
46
  :reason,
46
47
  :status,
@@ -46,7 +46,14 @@ describe Braintree::Dispute do
46
46
  :order_id => nil,
47
47
  :purchase_order_number => "po",
48
48
  :payment_instrument_subtype => "Visa",
49
- }
49
+ },
50
+ :paypal_messages => [
51
+ {
52
+ :message => "message",
53
+ :sender => "seller",
54
+ :sent_at => Time.utc(2009, 3, 9, 10, 50, 39),
55
+ }
56
+ ]
50
57
  }
51
58
  end
52
59
 
@@ -348,6 +355,16 @@ describe Braintree::Dispute do
348
355
  evidence2.url.should == nil
349
356
  end
350
357
 
358
+ it "converts paypal_messages hash into an array of Dispute::PayPalMessage objects" do
359
+ dispute = Braintree::Dispute._new(attributes)
360
+
361
+ dispute.paypal_messages.length.should == 1
362
+ paypal_message_1 = dispute.paypal_messages.first
363
+ paypal_message_1.message.should == "message"
364
+ paypal_message_1.sender.should == "seller"
365
+ paypal_message_1.sent_at.should == Time.utc(2009, 3, 9, 10, 50, 39)
366
+ end
367
+
351
368
  it "handles nil evidence" do
352
369
  attributes.delete(:evidence)
353
370
 
@@ -356,6 +373,14 @@ describe Braintree::Dispute do
356
373
  dispute.evidence.should == nil
357
374
  end
358
375
 
376
+ it "handles nil paypal_messages" do
377
+ attributes.delete(:paypal_messages)
378
+
379
+ dispute = Braintree::Dispute._new(attributes)
380
+
381
+ dispute.paypal_messages.should == nil
382
+ end
383
+
359
384
  it "sets the older webhook fields for backwards compatibility" do
360
385
  dispute = Braintree::Dispute._new(attributes)
361
386
 
@@ -0,0 +1,31 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::PaymentMethodNonceDetailsPayerInfo do
4
+ let(:payment_method_nonce_details_payer_info) {
5
+ Braintree::PaymentMethodNonceDetailsPayerInfo.new(
6
+ :billing_agreement_id => "billing-agreement-id",
7
+ :country_code => "US",
8
+ :email => "test@example.com",
9
+ :first_name => "First",
10
+ :last_name => "Last",
11
+ :payer_id => "payer-id",
12
+ )
13
+ }
14
+
15
+ describe "#initialize" do
16
+ it "sets attributes" do
17
+ payment_method_nonce_details_payer_info.billing_agreement_id.should == "billing-agreement-id"
18
+ payment_method_nonce_details_payer_info.country_code.should == "US"
19
+ payment_method_nonce_details_payer_info.email.should == "test@example.com"
20
+ payment_method_nonce_details_payer_info.first_name.should == "First"
21
+ payment_method_nonce_details_payer_info.last_name.should == "Last"
22
+ payment_method_nonce_details_payer_info.payer_id.should == "payer-id"
23
+ end
24
+ end
25
+
26
+ describe "inspect" do
27
+ it "prints the attributes" do
28
+ payment_method_nonce_details_payer_info.inspect.should == %(#<PaymentMethodNonceDetailsPayerInfo billing_agreement_id: \"billing-agreement-id\", country_code: \"US\", email: \"test@example.com\", first_name: \"First\", last_name: \"Last\", payer_id: \"payer-id\">)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::PaymentMethodNonceDetails do
4
+ let(:payment_method_nonce_details) {
5
+ Braintree::PaymentMethodNonceDetails.new(
6
+ :bin => "bin",
7
+ :card_type => "American Express",
8
+ :expiration_month => "12",
9
+ :expiration_year => "2025",
10
+ :is_network_tokenized => true,
11
+ :last_two => "11",
12
+ :payer_info => {
13
+ :billing_agreement_id => "1234",
14
+ :country_code => "US",
15
+ },
16
+ )
17
+ }
18
+
19
+ describe "#initialize" do
20
+ it "sets attributes" do
21
+ payment_method_nonce_details.bin.should == "bin"
22
+ payment_method_nonce_details.card_type.should == "American Express"
23
+ payment_method_nonce_details.expiration_month.should == "12"
24
+ payment_method_nonce_details.expiration_year.should == "2025"
25
+ payment_method_nonce_details.is_network_tokenized.should == true
26
+ payment_method_nonce_details.last_two.should == "11"
27
+ payment_method_nonce_details.payer_info.billing_agreement_id.should == "1234"
28
+ payment_method_nonce_details.payer_info.country_code.should == "US"
29
+ end
30
+ end
31
+
32
+ describe "inspect" do
33
+ it "prints the attributes" do
34
+ payment_method_nonce_details.inspect.should == %(#<PaymentMethodNonceDetails bin: "bin", card_type: "American Express", expiration_month: "12", expiration_year: "2025", is_network_tokenized: true, last_two: "11", payer_info: #<PaymentMethodNonceDetailsPayerInfo billing_agreement_id: "1234", country_code: "US", email: nil, first_name: nil, last_name: nil, payer_id: nil>>)
35
+ end
36
+ end
37
+
38
+ describe "is_network_tokenized" do
39
+ it "is aliased to is_network_tokenized?" do
40
+ payment_method_nonce_details.is_network_tokenized?.should == true
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::Xml::Rexml do
4
+ describe "self.parse" do
5
+ it "typecasts integers" do
6
+ xml = "<root><foo type=\"integer\">123</foo></root>"
7
+ Braintree::Xml::Rexml.parse(xml).should == {"root"=>{"foo"=>{"__content__"=>"123", "type"=>"integer"}}}
8
+ end
9
+
10
+ it "works with dashes or underscores" do
11
+ xml = <<-END
12
+ <root>
13
+ <dash-es />
14
+ <under_scores />
15
+ </root>
16
+ END
17
+ Braintree::Xml::Rexml.parse(xml).should == {"root"=>{"dash-es"=>{}, "under_scores"=>{}}}
18
+ end
19
+
20
+ it "uses nil if nil=true, otherwise uses empty string" do
21
+ xml = <<-END
22
+ <root>
23
+ <a_nil_value nil="true"></a_nil_value>
24
+ <an_empty_string></an_empty_string>
25
+ </root>
26
+ END
27
+ Braintree::Xml::Rexml.parse(xml).should == {"root"=>{"a_nil_value"=>{"nil"=>"true"}, "an_empty_string"=>{}}}
28
+ end
29
+
30
+ it "typecasts dates and times" do
31
+ xml = <<-END
32
+ <root>
33
+ <created-at type="datetime">2009-10-28T10:19:49Z</created-at>
34
+ </root>
35
+ END
36
+ Braintree::Xml::Rexml.parse(xml).should == {"root"=>{"created-at"=>{"__content__"=>"2009-10-28T10:19:49Z", "type"=>"datetime"}}}
37
+ end
38
+
39
+ it "builds an array if type=array" do
40
+ xml = <<-END
41
+ <root>
42
+ <customers type="array">
43
+ <customer><name>Adam</name></customer>
44
+ <customer><name>Ben</name></customer>
45
+ </customers>
46
+ </root>
47
+ END
48
+ Braintree::Xml::Rexml.parse(xml).should == {"root"=>{"customers"=>{"type"=>"array", "customer"=>[{"name"=>{"__content__"=>"Adam"}}, {"name"=>{"__content__"=>"Ben"}}]}}}
49
+ end
50
+ end
51
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-12 00:00:00.000000000 Z
11
+ date: 2021-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.4
27
- - !ruby/object:Gem::Dependency
28
- name: libxml-ruby
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 3.2.0
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 3.2.0
41
27
  description: Resources and tools for developers to integrate Braintree's global payments
42
28
  platform.
43
29
  email: code@getbraintree.com
@@ -84,6 +70,7 @@ files:
84
70
  - lib/braintree/discount_gateway.rb
85
71
  - lib/braintree/dispute.rb
86
72
  - lib/braintree/dispute/evidence.rb
73
+ - lib/braintree/dispute/paypal_message.rb
87
74
  - lib/braintree/dispute/status_history.rb
88
75
  - lib/braintree/dispute/transaction.rb
89
76
  - lib/braintree/dispute/transaction_details.rb
@@ -121,6 +108,8 @@ files:
121
108
  - lib/braintree/payment_method.rb
122
109
  - lib/braintree/payment_method_gateway.rb
123
110
  - lib/braintree/payment_method_nonce.rb
111
+ - lib/braintree/payment_method_nonce_details.rb
112
+ - lib/braintree/payment_method_nonce_details_payer_info.rb
124
113
  - lib/braintree/payment_method_nonce_gateway.rb
125
114
  - lib/braintree/payment_method_parser.rb
126
115
  - lib/braintree/paypal_account.rb
@@ -192,6 +181,7 @@ files:
192
181
  - lib/braintree/xml/generator.rb
193
182
  - lib/braintree/xml/libxml.rb
194
183
  - lib/braintree/xml/parser.rb
184
+ - lib/braintree/xml/rexml.rb
195
185
  - lib/ssl/api_braintreegateway_com.ca.crt
196
186
  - lib/ssl/securetrust_ca.crt
197
187
  - spec/fixtures/files/bt_logo.png
@@ -268,6 +258,8 @@ files:
268
258
  - spec/unit/braintree/local_payment_completed_spec.rb
269
259
  - spec/unit/braintree/merchant_account_spec.rb
270
260
  - spec/unit/braintree/modification_spec.rb
261
+ - spec/unit/braintree/payment_method_nonce_details_payer_info_spec.rb
262
+ - spec/unit/braintree/payment_method_nonce_details_spec.rb
271
263
  - spec/unit/braintree/payment_method_spec.rb
272
264
  - spec/unit/braintree/paypal_account_spec.rb
273
265
  - spec/unit/braintree/resource_collection_spec.rb
@@ -295,6 +287,7 @@ files:
295
287
  - spec/unit/braintree/webhook_notification_spec.rb
296
288
  - spec/unit/braintree/xml/libxml_spec.rb
297
289
  - spec/unit/braintree/xml/parser_spec.rb
290
+ - spec/unit/braintree/xml/rexml_spec.rb
298
291
  - spec/unit/braintree/xml_spec.rb
299
292
  - spec/unit/braintree_spec.rb
300
293
  - spec/unit/spec_helper.rb
@@ -314,14 +307,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
314
307
  requirements:
315
308
  - - ">="
316
309
  - !ruby/object:Gem::Version
317
- version: 2.5.0
310
+ version: 2.6.0
318
311
  required_rubygems_version: !ruby/object:Gem::Requirement
319
312
  requirements:
320
313
  - - ">="
321
314
  - !ruby/object:Gem::Version
322
315
  version: '0'
323
316
  requirements: []
324
- rubygems_version: 3.0.8
317
+ rubygems_version: 3.2.17
325
318
  signing_key:
326
319
  specification_version: 4
327
320
  summary: Braintree Ruby Server SDK