braintree 2.102.0 → 2.103.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: 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