braintree 2.102.0 → 2.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dadf0e37290b308d07f0856ce1b98b46dd24545c7aabd504516f9a07c8d6937f
4
- data.tar.gz: 46cd35b0d94e2a48db329c7699df7288bf5db85a47bc965847db0ddb2b1794b9
3
+ metadata.gz: 10f04c7d14b1f7b5cb886dc0e1586f4141f290cb79487044c30fd172d9ff9019
4
+ data.tar.gz: 4a42a26dfa1d7704d7082655007afd90682ea88534fb85409ed069fe36d4fa95
5
5
  SHA512:
6
- metadata.gz: c8af0480b494e769733cb03fc98813483c085fb567be2962af22dc6cae2cd162e448693047da262796b2686dd4ec0c778eef26614e93a20410660667329f7061
7
- data.tar.gz: 4f046887ad84d29b41f09f6927ae5a7d19e0710a98ea5ce31355a74c7361805c1c0d3432e273a852862d8ccb0f5506baea60241785d4c0d105592fc988b71f67
6
+ metadata.gz: 7414378030c6d523174909aff0ab58e2374795f627284197cbc2eb6925c70a8073cb89e2d3707b8559860444f446cbd90ced534ff313e8e78072ecc284151ab5
7
+ data.tar.gz: 207eaabae526a8cd11ada06bcf6ce818f8c235df057f645470236f254f81c202023b42cedf2fd6b98d54092254375375c55fc1c07fe9aebafb543bb93a54ee03
@@ -76,8 +76,8 @@ module Braintree
76
76
 
77
77
  def self._shared_signature # :nodoc:
78
78
  [:company, :country_code_alpha2, :country_code_alpha3, :country_code_numeric,
79
- :country_name, :extended_address, :first_name,
80
- :last_name, :locality, :postal_code, :region, :street_address]
79
+ :country_name, :extended_address, :first_name, :last_name, :locality, :phone_number,
80
+ :postal_code, :region, :street_address]
81
81
  end
82
82
 
83
83
  def self._update_signature # :nodoc:
@@ -239,6 +239,10 @@ module Braintree
239
239
  @venmo_sdk
240
240
  end
241
241
 
242
+ def is_network_tokenized?
243
+ @is_network_tokenized
244
+ end
245
+
242
246
  class << self
243
247
  protected :new
244
248
  end
@@ -247,7 +251,7 @@ module Braintree
247
251
  [
248
252
  :billing_address, :bin, :card_type, :cardholder_name, :created_at, :customer_id, :expiration_month,
249
253
  :expiration_year, :last_4, :token, :updated_at, :prepaid, :payroll, :product_id, :commercial, :debit, :durbin_regulated,
250
- :healthcare, :country_of_issuance, :issuing_bank, :image_url
254
+ :healthcare, :country_of_issuance, :issuing_bank, :image_url, :is_network_tokenized?
251
255
  ]
252
256
  end
253
257
 
@@ -27,6 +27,7 @@ module Braintree
27
27
  attr_reader :merchant_account_id
28
28
  attr_reader :network_response_code
29
29
  attr_reader :network_response_text
30
+ attr_reader :network_transaction_id
30
31
  attr_reader :processor_response_code
31
32
  attr_reader :processor_response_text
32
33
  attr_reader :processor_response_type
@@ -4,6 +4,7 @@ module Braintree
4
4
  include BaseModule
5
5
 
6
6
  attr_reader :amount
7
+ attr_reader :created_at
7
8
  attr_reader :id
8
9
  attr_reader :order_id
9
10
  attr_reader :purchase_order_number
@@ -303,6 +303,7 @@ module Braintree
303
303
  AmountMustBeGreaterThanZero = "81531"
304
304
  AmountNotSupportedByProcessor = "815193"
305
305
  BillingAddressConflict = "91530"
306
+ BillingPhoneNumberIsInvalid = "915206"
306
307
  CannotBeVoided = "91504"
307
308
  CannotCancelRelease = "91562"
308
309
  CannotCloneCredit = "91543"
@@ -376,6 +377,7 @@ module Braintree
376
377
  ProcessorDoesNotSupportUpdatingOrderId = "915107"
377
378
  ProcessorDoesNotSupportUpdatingTransactionDetails = "915130"
378
379
  ProcessorDoesNotSupportVoiceAuthorizations = "91545"
380
+ ProductSkuIsInvalid = "915202"
379
381
  PurchaseOrderNumberIsInvalid = "91548"
380
382
  PurchaseOrderNumberIsTooLong = "91537"
381
383
  RefundAmountIsTooLarge = "91521"
@@ -393,6 +395,8 @@ module Braintree
393
395
  ShippingAmountCannotBeNegative = "915163"
394
396
  ShippingAmountFormatIsInvalid = "915162"
395
397
  ShippingAmountIsTooLarge = "915164"
398
+ ShippingMethodIsInvalid = "915203"
399
+ ShippingPhoneNumberIsInvalid = "915204"
396
400
  ShipsFromPostalCodeInvalidCharacters = "915167"
397
401
  ShipsFromPostalCodeIsInvalid = "915166"
398
402
  ShipsFromPostalCodeIsTooLong = "915165"
@@ -800,5 +804,14 @@ module Braintree
800
804
  UnableToConfirmDepositAmounts = "96105"
801
805
  InvalidDepositAmounts = "96106"
802
806
  end
807
+
808
+ module RiskData
809
+ CustomerBrowserIsTooLong = "94701"
810
+ CustomerDeviceIdIsTooLong = "94702"
811
+ CustomerLocationZipInvalidCharacters = "94703"
812
+ CustomerLocationZipIsInvalid = "94704"
813
+ CustomerLocationZipIsTooLong = "94705"
814
+ CustomerTenureIsTooLong = "94706"
815
+ end
803
816
  end
804
817
  end
@@ -2,10 +2,13 @@ module Braintree
2
2
  class RiskData # :nodoc:
3
3
  include BaseModule
4
4
 
5
+ attr_reader :customer_device_id
6
+ attr_reader :customer_location_zip
7
+ attr_reader :customer_tenure
5
8
  attr_reader :decision
6
9
  attr_reader :device_data_captured
7
- attr_reader :id
8
10
  attr_reader :fraud_service_provider
11
+ attr_reader :id
9
12
 
10
13
  def initialize(attributes)
11
14
  set_instance_variables_from_hash attributes unless attributes.nil?
@@ -40,6 +40,7 @@ module Braintree
40
40
  VisaPrepaid = "4500600000000061"
41
41
 
42
42
  Fraud = "4000111111111511"
43
+ RiskThreshold = "4111130000000003"
43
44
 
44
45
  Visas = %w[4009348888881881 4012888888881881 4111111111111111 4000111111111115 4500600000000061]
45
46
  Unknowns = %w[1000000000000008]
@@ -62,6 +62,7 @@ module Braintree
62
62
  PayPalFuturePaymentRefreshToken = "fake-paypal-future-refresh-token-nonce"
63
63
  SEPA = "fake-sepa-bank-account-nonce"
64
64
  GatewayRejectedFraud = "fake-gateway-rejected-fraud-nonce"
65
+ GatewayRejectedRiskThresholds = "fake-gateway-rejected-risk-thresholds-nonce"
65
66
  MasterpassAmEx = "fake-masterpass-amex-nonce"
66
67
  MasterpassDiscover = "fake-masterpass-discover-nonce"
67
68
  MasterpassMasterCard = "fake-masterpass-mastercard-nonce"
@@ -25,6 +25,7 @@ module Braintree
25
25
  CVV = "cvv"
26
26
  Duplicate = "duplicate"
27
27
  Fraud = "fraud"
28
+ RiskThreshold = "risk_threshold"
28
29
  ThreeDSecure = "three_d_secure"
29
30
  TokenIssuance = "token_issuance"
30
31
  Unrecognized = "unrecognized"
@@ -142,6 +143,7 @@ module Braintree
142
143
  attr_reader :processor_response_type # Response type from the processor.
143
144
  attr_reader :processor_settlement_response_code # Settlement response code from the processor.
144
145
  attr_reader :processor_settlement_response_text # Settlement response text from the processor.
146
+ attr_reader :product_sku
145
147
  attr_reader :purchase_order_number
146
148
  attr_reader :recurring
147
149
  attr_reader :refund_ids
@@ -439,6 +441,10 @@ module Braintree
439
441
  return_object_or_raise(:transaction) { void }
440
442
  end
441
443
 
444
+ def processed_with_network_token?
445
+ @processed_with_network_token
446
+ end
447
+
442
448
  class << self
443
449
  protected :new
444
450
  def _new(*args) # :nodoc:
@@ -447,7 +453,7 @@ module Braintree
447
453
  end
448
454
 
449
455
  def self._attributes # :nodoc:
450
- [:amount, :created_at, :credit_card_details, :customer_details, :id, :status, :subscription_details, :type, :updated_at]
456
+ [:amount, :created_at, :credit_card_details, :customer_details, :id, :status, :subscription_details, :type, :updated_at, :processed_with_network_token?]
451
457
  end
452
458
  end
453
459
  end
@@ -3,6 +3,15 @@ module Braintree
3
3
  class AddressDetails # :nodoc:
4
4
  include BaseModule
5
5
 
6
+ module ShippingMethod
7
+ SameDay = "same_day"
8
+ NextDay = "next_day"
9
+ Priority = "priority"
10
+ Ground = "ground"
11
+ Electronic = "electronic"
12
+ ShipToStore = "ship_to_store"
13
+ end
14
+
6
15
  attr_reader :company
7
16
  attr_reader :country_code_alpha2
8
17
  attr_reader :country_code_alpha3
@@ -13,8 +22,10 @@ module Braintree
13
22
  attr_reader :id
14
23
  attr_reader :last_name
15
24
  attr_reader :locality
25
+ attr_reader :phone_number
16
26
  attr_reader :postal_code
17
27
  attr_reader :region
28
+ attr_reader :shipping_method
18
29
  attr_reader :street_address
19
30
 
20
31
  def initialize(attributes)
@@ -190,15 +190,16 @@ module Braintree
190
190
  :shipping_amount, :discount_amount, :ships_from_postal_code,
191
191
  :billing_address_id, :payment_method_nonce, :three_d_secure_token, :three_d_secure_authentication_id,
192
192
  :shared_payment_method_token, :shared_billing_address_id, :shared_customer_id, :shared_shipping_address_id, :shared_payment_method_nonce,
193
+ :product_sku,
193
194
  {:line_items => [:quantity, :name, :description, :kind, :unit_amount, :unit_tax_amount, :total_amount, :discount_amount, :tax_amount, :unit_of_measure, :product_code, :commodity_code, :url]},
194
- {:risk_data => [:customer_browser, :customer_ip]},
195
+ {:risk_data => [:customer_browser, :customer_device_id, :customer_ip, :customer_location_zip, :customer_tenure]},
195
196
  {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number]},
196
197
  {:customer => [:id, :company, :email, :fax, :first_name, :last_name, :phone, :website]},
197
198
  {
198
199
  :billing => AddressGateway._shared_signature
199
200
  },
200
201
  {
201
- :shipping => AddressGateway._shared_signature
202
+ :shipping => AddressGateway._shared_signature + [:shipping_method],
202
203
  },
203
204
  {
204
205
  :three_d_secure_pass_thru => [
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 2
4
- Minor = 102
4
+ Minor = 103
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
@@ -56,59 +56,84 @@ def nonce_for_paypal_account(paypal_account_details)
56
56
  end
57
57
 
58
58
  def generate_non_plaid_us_bank_account_nonce(account_number="1000000000")
59
- raw_client_token = Braintree::ClientToken.generate
60
- client_token = decode_client_token(raw_client_token)
59
+ query = %{
60
+ mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
61
+ tokenizeUsBankAccount(input: $input) {
62
+ paymentMethod {
63
+ id
64
+ }
65
+ }
66
+ }
67
+ }
61
68
 
62
- url = client_token["braintree_api"]["url"] + "/tokens"
63
- token = client_token["braintree_api"]["access_token"]
64
- payload = {
65
- :type => "us_bank_account",
66
- :billing_address => {
67
- :street_address => "123 Ave",
68
- :region => "CA",
69
- :locality => "San Francisco",
70
- :postal_code => "94112"
71
- },
72
- :account_type => "checking",
73
- :routing_number => "021000021",
74
- :account_number => account_number,
75
- :first_name => "John",
76
- :last_name => "Doe",
77
- :ownership_type => "personal",
78
- :ach_mandate => {
79
- :text => "cl mandate text"
69
+ variables = {
70
+ :input => {
71
+ :usBankAccount => {
72
+ :accountNumber => account_number,
73
+ :routingNumber => "021000021",
74
+ :accountType => "CHECKING",
75
+ :individualOwner => {
76
+ :firstName => "John",
77
+ :lastName => "Doe",
78
+ },
79
+ :billingAddress => {
80
+ :streetAddress => "123 Ave",
81
+ :state => "CA",
82
+ :city => "San Francisco",
83
+ :zipCode => "94112"
84
+ },
85
+ :achMandate => "cl mandate text"
86
+ }
80
87
  }
81
88
  }
82
89
 
83
- json = _cosmos_post(token, url, payload)
84
- json["data"]["id"]
90
+ graphql_request = {
91
+ :query => query,
92
+ :variables => variables
93
+ }
94
+
95
+ json = _send_graphql_request(graphql_request)
96
+ json["data"]["tokenizeUsBankAccount"]["paymentMethod"]["id"]
85
97
  end
86
98
 
87
99
  def generate_valid_plaid_us_bank_account_nonce
88
- raw_client_token = Braintree::ClientToken.generate
89
- client_token = decode_client_token(raw_client_token)
100
+ query = %{
101
+ mutation TokenizeUsBankLogin($input: TokenizeUsBankLoginInput!) {
102
+ tokenizeUsBankLogin(input: $input) {
103
+ paymentMethod {
104
+ id
105
+ }
106
+ }
107
+ }
108
+ }
90
109
 
91
- url = client_token["braintree_api"]["url"] + "/tokens"
92
- token = client_token["braintree_api"]["access_token"]
93
- payload = {
94
- :type => "plaid_public_token",
95
- :public_token => "good",
96
- :account_id => "plaid_account_id",
97
- :ownership_type => "business",
98
- :business_name => "PayPal, Inc.",
99
- :billing_address => {
100
- :street_address => "123 Ave",
101
- :region => "CA",
102
- :locality => "San Francisco",
103
- :postal_code => "94112"
104
- },
105
- :ach_mandate => {
106
- :text => "cl mandate text"
110
+ variables = {
111
+ :input => {
112
+ :usBankLogin => {
113
+ :publicToken => "good",
114
+ :accountId => "plaid_account_id",
115
+ :accountType => "CHECKING",
116
+ :businessOwner => {
117
+ :businessName => "PayPal, Inc.",
118
+ },
119
+ :billingAddress => {
120
+ :streetAddress => "123 Ave",
121
+ :state => "CA",
122
+ :city => "San Francisco",
123
+ :zipCode => "94112"
124
+ },
125
+ :achMandate => "cl mandate text"
126
+ }
107
127
  }
108
128
  }
109
129
 
110
- json = _cosmos_post(token, url, payload)
111
- json["data"]["id"]
130
+ graphql_request = {
131
+ :query => query,
132
+ :variables => variables
133
+ }
134
+
135
+ json = _send_graphql_request(graphql_request)
136
+ json["data"]["tokenizeUsBankLogin"]["paymentMethod"]["id"]
112
137
  end
113
138
 
114
139
  def generate_valid_ideal_payment_nonce(amount = Braintree::Test::TransactionAmounts::Authorize)
@@ -120,8 +145,10 @@ def generate_valid_ideal_payment_nonce(amount = Braintree::Test::TransactionAmou
120
145
  )
121
146
  config = JSON.parse(client.get_configuration.body)
122
147
 
123
- token = client_token["braintree_api"]["access_token"]
124
- url = client_token["braintree_api"]["url"] + "/ideal-payments"
148
+ braintree_api = client_token["braintree_api"]
149
+ url = braintree_api["url"] + "/ideal-payments"
150
+
151
+ token = braintree_api["access_token"]
125
152
  payload = {
126
153
  :issuer => "RABONL2U",
127
154
  :order_id => SpecHelper::DefaultOrderId,
@@ -149,8 +176,10 @@ end
149
176
  def _cosmos_post(token, url, payload)
150
177
  uri = URI::parse(url)
151
178
  connection = Net::HTTP.new(uri.host, uri.port)
152
- connection.use_ssl = true
153
- connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
179
+ if uri.scheme == "https"
180
+ connection.use_ssl = true
181
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
182
+ end
154
183
  resp = connection.start do |http|
155
184
  request = Net::HTTP::Post.new(uri.path)
156
185
  request["Content-Type"] = "application/json"
@@ -163,6 +192,29 @@ def _cosmos_post(token, url, payload)
163
192
  JSON.parse(resp.body)
164
193
  end
165
194
 
195
+ def _send_graphql_request(graphql_request)
196
+ raw_client_token = Braintree::ClientToken.generate
197
+ client_token = decode_client_token(raw_client_token)
198
+ uri = URI::parse("#{client_token["braintree_api"]["url"]}/graphql")
199
+ connection = Net::HTTP.new(uri.host, uri.port)
200
+
201
+ if uri.scheme == "https"
202
+ connection.use_ssl = true
203
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
204
+ end
205
+
206
+ resp = connection.start do |http|
207
+ request = Net::HTTP::Post.new(uri.path)
208
+ request["Content-Type"] = "application/json"
209
+ request["Braintree-Version"] = "2016-10-07"
210
+ request["Authorization"] = "Bearer #{client_token["braintree_api"]["access_token"]}"
211
+ request.body = graphql_request.to_json
212
+ http.request(request)
213
+ end
214
+
215
+ JSON.parse(resp.body)
216
+ end
217
+
166
218
  class ClientApiHttp
167
219
  attr_reader :config, :options
168
220
 
@@ -15,7 +15,7 @@ describe Braintree::CreditCard do
15
15
  :customer_id => customer.id,
16
16
  :number => Braintree::Test::CreditCardNumbers::Visa,
17
17
  :expiration_date => "05/2009",
18
- :cvv => "100"
18
+ :cvv => "100",
19
19
  )
20
20
  result.success?.should == true
21
21
  credit_card = result.credit_card
@@ -1851,4 +1851,22 @@ describe Braintree::CreditCard do
1851
1851
  credit_card.nonce.should_not be_nil
1852
1852
  end
1853
1853
  end
1854
+
1855
+ describe "card on file network tokenization" do
1856
+ it "should find a network tokenized credit card" do
1857
+ credit_card = Braintree::CreditCard.find("network_tokenized_credit_card")
1858
+ credit_card.is_network_tokenized?.should == true
1859
+ end
1860
+
1861
+ it "should find a non-network tokenized credit card" do
1862
+ customer = Braintree::Customer.create!
1863
+ credit_card = Braintree::CreditCard.create(
1864
+ :customer_id => customer.id,
1865
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1866
+ :expiration_date => "05/2009"
1867
+ ).credit_card
1868
+ credit_card_vaulted = Braintree::CreditCard.find(credit_card.token)
1869
+ credit_card_vaulted.is_network_tokenized?.should == false
1870
+ end
1871
+ end
1854
1872
  end
@@ -22,6 +22,7 @@ describe Braintree::CreditCardVerification, "search" do
22
22
  result.credit_card_verification.processor_response_code.should == "1000"
23
23
  result.credit_card_verification.processor_response_text.should == "Approved"
24
24
  result.credit_card_verification.processor_response_type.should == Braintree::ProcessorResponseTypes::Approved
25
+ expect(result.credit_card_verification.network_transaction_id).not_to be_nil
25
26
  end
26
27
 
27
28
  it "creates a new verification with network response code/text" do
@@ -140,6 +140,31 @@ describe Braintree::Transaction do
140
140
  result.transaction.risk_data.should respond_to(:fraud_service_provider)
141
141
  end
142
142
  end
143
+
144
+ it "handles validation errors for invalid risk data attributes" do
145
+ with_advanced_fraud_integration_merchant do
146
+ result = Braintree::Transaction.create(
147
+ :type => "sale",
148
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
149
+ :credit_card => {
150
+ :number => Braintree::Test::CreditCardNumbers::Visa,
151
+ :expiration_date => "05/2009"
152
+ },
153
+ :risk_data => {
154
+ :customer_browser => "#{"1" * 300}",
155
+ :customer_device_id => "customer_device_id_0#{"1" * 300}",
156
+ :customer_ip => "192.168.0.1",
157
+ :customer_location_zip => "not-a-$#phone",
158
+ :customer_tenure => "20#{"0" * 500}"
159
+ }
160
+ )
161
+ result.success?.should == false
162
+ result.errors.for(:transaction).for(:risk_data).on(:customer_browser).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerBrowserIsTooLong
163
+ result.errors.for(:transaction).for(:risk_data).on(:customer_device_id).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerDeviceIdIsTooLong
164
+ result.errors.for(:transaction).for(:risk_data).on(:customer_location_zip).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerLocationZipInvalidCharacters
165
+ result.errors.for(:transaction).for(:risk_data).on(:customer_tenure).map { |e| e.code }.should include Braintree::ErrorCodes::RiskData::CustomerTenureIsTooLong
166
+ end
167
+ end
143
168
  end
144
169
 
145
170
  describe "card type indicators" do
@@ -499,7 +524,7 @@ describe Braintree::Transaction do
499
524
  result.success?.should == true
500
525
  end
501
526
 
502
- it "accepts additional security parameters: risk data with customer_browser and customer_ip" do
527
+ it "accepts additional security parameters: risk data" do
503
528
  result = Braintree::Transaction.create(
504
529
  :type => "sale",
505
530
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -509,7 +534,10 @@ describe Braintree::Transaction do
509
534
  },
510
535
  :risk_data => {
511
536
  :customer_browser => "IE6",
512
- :customer_ip => "192.168.0.1"
537
+ :customer_device_id => "customer_device_id_012",
538
+ :customer_ip => "192.168.0.1",
539
+ :customer_location_zip => "91244",
540
+ :customer_tenure => "20",
513
541
  }
514
542
  )
515
543
 
@@ -688,6 +716,68 @@ describe Braintree::Transaction do
688
716
  codes.should include(Braintree::ErrorCodes::Address::CountryCodeNumericIsNotAccepted)
689
717
  end
690
718
 
719
+ it "returns an error if provided product sku is invalid" do
720
+ result = Braintree::Transaction.sale(
721
+ :amount => "100",
722
+ :credit_card => {
723
+ :number => "5105105105105100",
724
+ :expiration_date => "05/2012"
725
+ },
726
+ :product_sku => "product$ku!",
727
+ )
728
+
729
+ result.success?.should == false
730
+ result.errors.for(:transaction).on(:product_sku).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ProductSkuIsInvalid)
731
+ end
732
+
733
+ it "returns an error if provided shipping phone number is invalid" do
734
+ result = Braintree::Transaction.sale(
735
+ :amount => "100",
736
+ :credit_card => {
737
+ :number => "5105105105105100",
738
+ :expiration_date => "05/2012"
739
+ },
740
+ :shipping => {
741
+ :phone_number => "123-234-3456=098765"
742
+ }
743
+ )
744
+
745
+ result.success?.should == false
746
+ result.errors.for(:transaction).for(:shipping).on(:phone_number).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ShippingPhoneNumberIsInvalid)
747
+ end
748
+
749
+ it "returns an error if provided shipping method is invalid" do
750
+ result = Braintree::Transaction.sale(
751
+ :amount => "100",
752
+ :credit_card => {
753
+ :number => "5105105105105100",
754
+ :expiration_date => "05/2012"
755
+ },
756
+ :shipping => {
757
+ :shipping_method => "urgent"
758
+ }
759
+ )
760
+
761
+ result.success?.should == false
762
+ result.errors.for(:transaction).for(:shipping).on(:shipping_method).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::ShippingMethodIsInvalid)
763
+ end
764
+
765
+ it "returns an error if provided billing phone number is invalid" do
766
+ result = Braintree::Transaction.sale(
767
+ :amount => "100",
768
+ :credit_card => {
769
+ :number => "5105105105105100",
770
+ :expiration_date => "05/2012"
771
+ },
772
+ :billing => {
773
+ :phone_number => "123-234-3456=098765"
774
+ }
775
+ )
776
+
777
+ result.success?.should == false
778
+ result.errors.for(:transaction).for(:billing).on(:phone_number).map { |e| e.code }.should include(Braintree::ErrorCodes::Transaction::BillingPhoneNumberIsInvalid)
779
+ end
780
+
691
781
  context "gateway rejection reason" do
692
782
  it "exposes the cvv gateway rejection reason" do
693
783
  old_merchant = Braintree::Configuration.merchant_id
@@ -805,16 +895,44 @@ describe Braintree::Transaction do
805
895
  end
806
896
 
807
897
  it "exposes the fraud gateway rejection reason" do
808
- result = Braintree::Transaction.sale(
809
- :amount => Braintree::Test::TransactionAmounts::Authorize,
810
- :credit_card => {
811
- :number => Braintree::Test::CreditCardNumbers::Fraud,
812
- :expiration_date => "05/2017",
813
- :cvv => "333"
814
- }
815
- )
816
- result.success?.should == false
817
- result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::Fraud
898
+ with_advanced_fraud_integration_merchant do
899
+ result = Braintree::Transaction.sale(
900
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
901
+ :credit_card => {
902
+ :number => Braintree::Test::CreditCardNumbers::Fraud,
903
+ :expiration_date => "05/2017",
904
+ :cvv => "333"
905
+ }
906
+ )
907
+ result.success?.should == false
908
+ result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::Fraud
909
+ end
910
+ end
911
+
912
+ it "exposes the risk_threshold gateway rejection reason (via test cc num)" do
913
+ with_advanced_fraud_integration_merchant do
914
+ result = Braintree::Transaction.sale(
915
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
916
+ :credit_card => {
917
+ :number => Braintree::Test::CreditCardNumbers::RiskThreshold,
918
+ :expiration_date => "05/2017",
919
+ :cvv => "333"
920
+ }
921
+ )
922
+ result.success?.should == false
923
+ result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::RiskThreshold
924
+ end
925
+ end
926
+
927
+ it "exposes the risk_threshold gateway rejection reason (via test test nonce)" do
928
+ with_advanced_fraud_integration_merchant do
929
+ result = Braintree::Transaction.sale(
930
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
931
+ :payment_method_nonce => Braintree::Test::Nonce::GatewayRejectedRiskThresholds,
932
+ )
933
+ result.success?.should == false
934
+ result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::RiskThreshold
935
+ end
818
936
  end
819
937
 
820
938
  it "exposes the token issuance gateway rejection reason" do
@@ -4536,6 +4654,7 @@ describe Braintree::Transaction do
4536
4654
  result = Braintree::Transaction.sale(
4537
4655
  :amount => "100.00",
4538
4656
  :order_id => "123",
4657
+ :product_sku => "productsku01",
4539
4658
  :channel => "MyShoppingCartProvider",
4540
4659
  :credit_card => {
4541
4660
  :cardholder_name => "The Cardholder",
@@ -4560,6 +4679,7 @@ describe Braintree::Transaction do
4560
4679
  :extended_address => "Suite 403",
4561
4680
  :locality => "Chicago",
4562
4681
  :region => "IL",
4682
+ :phone_number => "122-555-1237",
4563
4683
  :postal_code => "60622",
4564
4684
  :country_name => "United States of America"
4565
4685
  },
@@ -4571,8 +4691,10 @@ describe Braintree::Transaction do
4571
4691
  :extended_address => "Apt 2F",
4572
4692
  :locality => "Bartlett",
4573
4693
  :region => "IL",
4694
+ :phone_number => "122-555-1236",
4574
4695
  :postal_code => "60103",
4575
- :country_name => "United States of America"
4696
+ :country_name => "United States of America",
4697
+ :shipping_method => Braintree::Transaction::AddressDetails::ShippingMethod::Electronic
4576
4698
  }
4577
4699
  )
4578
4700
  result.success?.should == true
@@ -7039,4 +7161,37 @@ describe Braintree::Transaction do
7039
7161
  details.refund_id.should_not be_nil
7040
7162
  end
7041
7163
  end
7164
+
7165
+ describe "card on file network tokenization" do
7166
+ it "creates a transaction with a vaulted, tokenized credit card" do
7167
+ result = Braintree::Transaction.sale(
7168
+ :amount => "112.44",
7169
+ :payment_method_token => "network_tokenized_credit_card",
7170
+ )
7171
+ result.success?.should == true
7172
+ transaction = result.transaction
7173
+
7174
+ transaction.amount.should == BigDecimal("112.44")
7175
+ transaction.processed_with_network_token?.should == true
7176
+ end
7177
+
7178
+ it "creates a transaction with a vaulted, non-tokenized credit card" do
7179
+ customer = Braintree::Customer.create!
7180
+ result = Braintree::PaymentMethod.create(
7181
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
7182
+ :customer_id => customer.id
7183
+ )
7184
+ payment_method_token = result.payment_method.token
7185
+
7186
+ result = Braintree::Transaction.sale(
7187
+ :amount => "112.44",
7188
+ :payment_method_token => payment_method_token,
7189
+ )
7190
+ result.success?.should == true
7191
+ transaction = result.transaction
7192
+
7193
+ transaction.amount.should == BigDecimal("112.44")
7194
+ transaction.processed_with_network_token?.should == false
7195
+ end
7196
+ end
7042
7197
  end
@@ -37,6 +37,7 @@ describe Braintree::CreditCard do
37
37
  :first_name,
38
38
  :last_name,
39
39
  :locality,
40
+ :phone_number,
40
41
  :postal_code,
41
42
  :region,
42
43
  :street_address
@@ -84,6 +85,7 @@ describe Braintree::CreditCard do
84
85
  :first_name,
85
86
  :last_name,
86
87
  :locality,
88
+ :phone_number,
87
89
  :postal_code,
88
90
  :region,
89
91
  :street_address,
@@ -196,7 +198,8 @@ describe Braintree::CreditCard do
196
198
  :expiration_year => "2020",
197
199
  :last_4 => "1111",
198
200
  :token => "tok1",
199
- :updated_at => Time.now
201
+ :updated_at => Time.now,
202
+ :is_network_tokenized => false,
200
203
  )
201
204
  output = credit_card.inspect
202
205
  output.should include(%q(bin: "411111"))
@@ -210,6 +213,7 @@ describe Braintree::CreditCard do
210
213
  output.should include(%q(token: "tok1"))
211
214
  output.should include(%Q(updated_at: #{credit_card.updated_at.inspect}))
212
215
  output.should include(%Q(created_at: #{credit_card.created_at.inspect}))
216
+ output.should include(%q(is_network_tokenized?: false))
213
217
  end
214
218
  end
215
219
 
@@ -224,6 +228,28 @@ describe Braintree::CreditCard do
224
228
  end
225
229
  end
226
230
 
231
+ describe "is_network_tokenized?" do
232
+ it "returns true" do
233
+ credit_card = Braintree::CreditCard._new(
234
+ :gateway,
235
+ :bin => "510510",
236
+ :last_4 => "5100",
237
+ :is_network_tokenized => true
238
+ )
239
+ credit_card.is_network_tokenized?.should == true
240
+ end
241
+
242
+ it "returns false" do
243
+ credit_card = Braintree::CreditCard._new(
244
+ :gateway,
245
+ :bin => "510510",
246
+ :last_4 => "5100",
247
+ :is_network_tokenized => false
248
+ )
249
+ credit_card.is_network_tokenized?.should == false
250
+ end
251
+ end
252
+
227
253
  describe "self.update" do
228
254
  it "raises an exception if attributes contain an invalid key" do
229
255
  expect do
@@ -42,6 +42,13 @@ describe Braintree::CreditCardVerification do
42
42
  Braintree::CreditCardVerification._new(:amount => BigDecimal("12.34")).amount.should == BigDecimal("12.34")
43
43
  end
44
44
 
45
+ it "accepts network_transaction_id" do
46
+ verification = Braintree::CreditCardVerification._new(
47
+ :network_transaction_id => "123456789012345"
48
+ )
49
+ expect(verification.network_transaction_id).to eq "123456789012345"
50
+ end
51
+
45
52
  describe "self.create" do
46
53
  it "rejects invalid parameters" do
47
54
  expect do
@@ -113,6 +113,7 @@ describe Braintree::Customer do
113
113
  :first_name,
114
114
  :last_name,
115
115
  :locality,
116
+ :phone_number,
116
117
  :postal_code,
117
118
  :region,
118
119
  :street_address
@@ -151,6 +152,7 @@ describe Braintree::Customer do
151
152
  :first_name,
152
153
  :last_name,
153
154
  :locality,
155
+ :phone_number,
154
156
  :postal_code,
155
157
  :region,
156
158
  :street_address,
@@ -211,6 +213,7 @@ describe Braintree::Customer do
211
213
  :first_name,
212
214
  :last_name,
213
215
  :locality,
216
+ :phone_number,
214
217
  :postal_code,
215
218
  :region,
216
219
  :street_address,
@@ -244,6 +247,7 @@ describe Braintree::Customer do
244
247
  :first_name,
245
248
  :last_name,
246
249
  :locality,
250
+ :phone_number,
247
251
  :postal_code,
248
252
  :region,
249
253
  :street_address,
@@ -319,6 +319,7 @@ describe Braintree::Dispute do
319
319
 
320
320
  dispute.transaction.amount.should == 31.00
321
321
  dispute.transaction.id.should == "open_disputed_transaction"
322
+ dispute.transaction.created_at.should == Time.utc(2009, 2, 9, 12, 59, 59)
322
323
  dispute.transaction.order_id.should == nil
323
324
  dispute.transaction.purchase_order_number.should == "po"
324
325
  dispute.transaction.payment_instrument_subtype.should == "Visa"
@@ -276,16 +276,18 @@ describe Braintree::Transaction do
276
276
  end
277
277
 
278
278
  describe "inspect" do
279
- it "includes the id, type, amount, and status first" do
279
+ it "includes the id, type, amount, status, and processed_with_network_token?" do
280
280
  transaction = Braintree::Transaction._new(
281
281
  :gateway,
282
282
  :id => "1234",
283
283
  :type => "sale",
284
284
  :amount => "100.00",
285
- :status => Braintree::Transaction::Status::Authorized
285
+ :status => Braintree::Transaction::Status::Authorized,
286
+ :processed_with_network_token => false,
286
287
  )
287
288
  output = transaction.inspect
288
289
  output.should include(%Q(#<Braintree::Transaction id: "1234", type: "sale", amount: "100.0", status: "authorized"))
290
+ output.should include(%Q(processed_with_network_token?: false))
289
291
  end
290
292
  end
291
293
 
@@ -394,4 +396,16 @@ describe Braintree::Transaction do
394
396
  )
395
397
  end
396
398
  end
399
+
400
+ describe "processed_with_network_token?" do
401
+ it "is true if the transaction was processed with a network token" do
402
+ transaction = Braintree::Transaction._new(:gateway, :processed_with_network_token => true)
403
+ transaction.processed_with_network_token?.should == true
404
+ end
405
+
406
+ it "is false if the transaction was not processed with a network token" do
407
+ transaction = Braintree::Transaction._new(:gateway, :processed_with_network_token => false)
408
+ transaction.processed_with_network_token?.should == false
409
+ end
410
+ end
397
411
  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: 2.102.0
4
+ version: 2.103.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-13 00:00:00.000000000 Z
11
+ date: 2020-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -321,8 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
321
321
  - !ruby/object:Gem::Version
322
322
  version: '0'
323
323
  requirements: []
324
- rubyforge_project:
325
- rubygems_version: 2.7.6.2
324
+ rubygems_version: 3.0.8
326
325
  signing_key:
327
326
  specification_version: 4
328
327
  summary: Braintree Gateway Ruby Client Library