braintree 2.102.0 → 3.1.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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/braintree.gemspec +6 -3
  4. data/lib/braintree.rb +3 -17
  5. data/lib/braintree/address.rb +0 -22
  6. data/lib/braintree/address_gateway.rb +2 -2
  7. data/lib/braintree/base_module.rb +6 -0
  8. data/lib/braintree/bin_data.rb +9 -2
  9. data/lib/braintree/configuration.rb +1 -1
  10. data/lib/braintree/credit_card.rb +5 -76
  11. data/lib/braintree/credit_card_gateway.rb +3 -32
  12. data/lib/braintree/credit_card_verification.rb +14 -0
  13. data/lib/braintree/customer.rb +3 -72
  14. data/lib/braintree/customer_gateway.rb +0 -23
  15. data/lib/braintree/dispute.rb +1 -7
  16. data/lib/braintree/dispute/{history_event.rb → status_history.rb} +3 -1
  17. data/lib/braintree/dispute/transaction.rb +2 -0
  18. data/lib/braintree/dispute_gateway.rb +2 -7
  19. data/lib/braintree/error_codes.rb +152 -170
  20. data/lib/braintree/exceptions.rb +5 -3
  21. data/lib/braintree/gateway.rb +0 -14
  22. data/lib/braintree/{android_pay_card.rb → google_pay_card.rb} +1 -1
  23. data/lib/braintree/local_payment_completed.rb +1 -1
  24. data/lib/braintree/merchant_account_gateway.rb +2 -0
  25. data/lib/braintree/payment_instrument_type.rb +1 -4
  26. data/lib/braintree/payment_method_gateway.rb +4 -8
  27. data/lib/braintree/payment_method_parser.rb +1 -7
  28. data/lib/braintree/risk_data.rb +4 -1
  29. data/lib/braintree/subscription.rb +5 -5
  30. data/lib/braintree/successful_result.rb +0 -1
  31. data/lib/braintree/test/credit_card.rb +1 -0
  32. data/lib/braintree/test/nonce.rb +5 -20
  33. data/lib/braintree/transaction.rb +9 -73
  34. data/lib/braintree/transaction/address_details.rb +11 -0
  35. data/lib/braintree/transaction/disbursement_details.rb +1 -0
  36. data/lib/braintree/transaction/{android_pay_details.rb → google_pay_details.rb} +1 -1
  37. data/lib/braintree/transaction/paypal_details.rb +3 -0
  38. data/lib/braintree/transaction/subscription_details.rb +2 -0
  39. data/lib/braintree/transaction_gateway.rb +14 -21
  40. data/lib/braintree/transaction_search.rb +0 -1
  41. data/lib/braintree/util.rb +17 -2
  42. data/lib/braintree/version.rb +2 -2
  43. data/lib/braintree/webhook_notification.rb +0 -10
  44. data/lib/braintree/webhook_testing_gateway.rb +0 -43
  45. data/lib/braintree/xml/libxml.rb +1 -0
  46. data/lib/braintree/xml/parser.rb +11 -34
  47. data/spec/integration/braintree/address_spec.rb +2 -89
  48. data/spec/integration/braintree/client_api/spec_helper.rb +92 -66
  49. data/spec/integration/braintree/credit_card_spec.rb +20 -467
  50. data/spec/integration/braintree/credit_card_verification_spec.rb +1 -0
  51. data/spec/integration/braintree/customer_spec.rb +22 -362
  52. data/spec/integration/braintree/dispute_search_spec.rb +3 -3
  53. data/spec/integration/braintree/dispute_spec.rb +1 -2
  54. data/spec/integration/braintree/merchant_spec.rb +2 -2
  55. data/spec/integration/braintree/payment_method_spec.rb +77 -120
  56. data/spec/integration/braintree/paypal_account_spec.rb +1 -1
  57. data/spec/integration/braintree/subscription_spec.rb +11 -16
  58. data/spec/integration/braintree/transaction_search_spec.rb +3 -3
  59. data/spec/integration/braintree/transaction_spec.rb +274 -524
  60. data/spec/integration/spec_helper.rb +1 -4
  61. data/spec/spec_helper.rb +1 -11
  62. data/spec/unit/braintree/address_spec.rb +0 -8
  63. data/spec/unit/braintree/credit_card_spec.rb +28 -21
  64. data/spec/unit/braintree/credit_card_verification_spec.rb +7 -0
  65. data/spec/unit/braintree/customer_spec.rb +4 -12
  66. data/spec/unit/braintree/dispute_spec.rb +4 -12
  67. data/spec/unit/braintree/http_spec.rb +3 -3
  68. data/spec/unit/braintree/local_payment_completed_spec.rb +14 -0
  69. data/spec/unit/braintree/transaction/paypal_details_spec.rb +59 -0
  70. data/spec/unit/braintree/transaction_spec.rb +17 -37
  71. data/spec/unit/braintree/util_spec.rb +37 -3
  72. data/spec/unit/braintree/webhook_notification_spec.rb +1 -1
  73. data/spec/unit/braintree/xml/parser_spec.rb +21 -16
  74. metadata +28 -32
  75. data/lib/braintree/amex_express_checkout_card.rb +0 -38
  76. data/lib/braintree/coinbase_account.rb +0 -34
  77. data/lib/braintree/europe_bank_account.rb +0 -36
  78. data/lib/braintree/europe_bank_account_gateway.rb +0 -17
  79. data/lib/braintree/ideal_payment.rb +0 -61
  80. data/lib/braintree/ideal_payment_gateway.rb +0 -19
  81. data/lib/braintree/masterpass_card.rb +0 -81
  82. data/lib/braintree/transaction/amex_express_checkout_details.rb +0 -21
  83. data/lib/braintree/transaction/coinbase_details.rb +0 -16
  84. data/lib/braintree/transaction/ideal_payment_details.rb +0 -19
  85. data/lib/braintree/transaction/masterpass_card_details.rb +0 -47
  86. data/lib/braintree/transparent_redirect.rb +0 -40
  87. data/lib/braintree/transparent_redirect_gateway.rb +0 -105
  88. data/lib/braintree/xml/rexml.rb +0 -71
  89. data/spec/hacks/tcp_socket.rb +0 -18
  90. data/spec/integration/braintree/coinbase_spec.rb +0 -34
  91. data/spec/integration/braintree/masterpass_card_spec.rb +0 -97
  92. data/spec/integration/braintree/transparent_redirect_spec.rb +0 -268
  93. data/spec/unit/braintree/transparent_redirect_spec.rb +0 -223
  94. data/spec/unit/braintree/xml/rexml_spec.rb +0 -51
@@ -1,61 +0,0 @@
1
- module Braintree
2
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
3
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
4
- class IdealPayment
5
- include BaseModule
6
-
7
- attr_reader :amount
8
- attr_reader :approval_url
9
- attr_reader :currency
10
- attr_reader :iban_bank_account
11
- attr_reader :id
12
- attr_reader :ideal_transaction_id
13
- attr_reader :issuer
14
- attr_reader :order_id
15
- attr_reader :status
16
-
17
- def initialize(gateway, attributes) # :nodoc:
18
- @gateway = gateway
19
- set_instance_variables_from_hash(attributes)
20
- @iban_bank_account = IbanBankAccount.new(attributes[:iban_bank_account]) if attributes[:iban_bank_account]
21
- end
22
-
23
- class << self
24
- protected :new
25
- end
26
-
27
- def self._new(*args) # :nodoc:
28
- self.new *args
29
- end
30
-
31
- def self.sale(ideal_payment_id, transaction_attributes)
32
- Configuration.gateway.transaction.sale(transaction_attributes.merge(
33
- :payment_method_nonce => ideal_payment_id,
34
- :options => { :submit_for_settlement => true }
35
- )
36
- )
37
- end
38
-
39
- def self.sale!(ideal_payment_id, transaction_attributes)
40
- return_object_or_raise(:transaction) { sale(ideal_payment_id, transaction_attributes) }
41
- end
42
-
43
- def self.find(ideal_payment_id)
44
- Configuration.gateway.ideal_payment.find(ideal_payment_id)
45
- end
46
-
47
- class IbanBankAccount
48
- include BaseModule
49
- attr_reader :account_holder_name
50
- attr_reader :bic
51
- attr_reader :description
52
- attr_reader :iban_account_number_last_4
53
- attr_reader :iban_country
54
- attr_reader :masked_iban
55
-
56
- def initialize(attributes) # :nodoc:
57
- set_instance_variables_from_hash(attributes)
58
- end
59
- end
60
- end
61
- end
@@ -1,19 +0,0 @@
1
- module Braintree
2
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
3
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
4
- class IdealPaymentGateway
5
- def initialize(gateway)
6
- @gateway = gateway
7
- @config = gateway.config
8
- @config.assert_has_access_token_or_keys
9
- end
10
-
11
- def find(ideal_payment_id)
12
- raise ArgumentError if ideal_payment_id.nil? || ideal_payment_id.to_s.strip == ""
13
- response = @config.http.get("#{@config.base_merchant_path}/ideal_payments/#{ideal_payment_id}")
14
- IdealPayment._new(@gateway, response[:ideal_payment])
15
- rescue NotFoundError
16
- raise NotFoundError, "ideal payment with ideal_payment_id #{ideal_payment_id.inspect} not found"
17
- end
18
- end
19
- end
@@ -1,81 +0,0 @@
1
- module Braintree
2
- class MasterpassCard
3
- include BaseModule # :nodoc:
4
- include Braintree::Util::TokenEquality
5
-
6
- attr_reader :billing_address
7
- attr_reader :bin
8
- attr_reader :card_type
9
- attr_reader :cardholder_name
10
- attr_reader :commercial
11
- attr_reader :country_of_issuance
12
- attr_reader :created_at
13
- attr_reader :customer_id
14
- attr_reader :customer_location
15
- attr_reader :debit
16
- attr_reader :durbin_regulated
17
- attr_reader :expiration_month
18
- attr_reader :expiration_year
19
- attr_reader :healthcare
20
- attr_reader :image_url
21
- attr_reader :issuing_bank
22
- attr_reader :last_4
23
- attr_reader :payroll
24
- attr_reader :prepaid
25
- attr_reader :product_id
26
- attr_reader :subscriptions
27
- attr_reader :token
28
- attr_reader :unique_number_identifier
29
- attr_reader :updated_at
30
- attr_reader :verification
31
-
32
- def initialize(gateway, attributes) # :nodoc:
33
- @gateway = gateway
34
- set_instance_variables_from_hash(attributes)
35
- @billing_address = attributes[:billing_address] ? Address._new(@gateway, attributes[:billing_address]) : nil
36
- @subscriptions = (@subscriptions || []).map { |subscription_hash| Subscription._new(@gateway, subscription_hash) }
37
- @verification = _most_recent_verification(attributes)
38
- end
39
-
40
- def _most_recent_verification(attributes)
41
- verification = (attributes[:verifications] || []).sort_by{ |verification| verification[:created_at] }.reverse.first
42
- CreditCardVerification._new(verification) if verification
43
- end
44
-
45
- def default?
46
- @default
47
- end
48
-
49
- # Expiration date formatted as MM/YYYY
50
- def expiration_date
51
- "#{expiration_month}/#{expiration_year}"
52
- end
53
-
54
- def expired?
55
- @expired
56
- end
57
-
58
- def inspect # :nodoc:
59
- first = [:token]
60
- order = first + (self.class._attributes - first)
61
- nice_attributes = order.map do |attr|
62
- "#{attr}: #{send(attr).inspect}"
63
- end
64
- "#<#{self.class} #{nice_attributes.join(', ')}>"
65
- end
66
-
67
- def self._attributes # :nodoc:
68
- [
69
- :billing_address, :bin, :card_type, :cardholder_name, :created_at,
70
- :customer_id, :customer_location, :expiration_month, :expiration_year,
71
- :last_4, :token, :updated_at, :prepaid, :payroll, :product_id,
72
- :commercial, :debit, :durbin_regulated, :healthcare,
73
- :country_of_issuance, :issuing_bank, :image_url
74
- ]
75
- end
76
-
77
- def self._new(*args) # :nodoc:
78
- self.new *args
79
- end
80
- end
81
- end
@@ -1,21 +0,0 @@
1
- module Braintree
2
- class Transaction
3
- class AmexExpressCheckoutDetails
4
- include BaseModule
5
-
6
- attr_reader :bin
7
- attr_reader :card_member_expiry_date
8
- attr_reader :card_member_number
9
- attr_reader :card_type
10
- attr_reader :expiration_month
11
- attr_reader :expiration_year
12
- attr_reader :image_url
13
- attr_reader :source_description
14
- attr_reader :token
15
-
16
- def initialize(attributes)
17
- set_instance_variables_from_hash attributes unless attributes.nil?
18
- end
19
- end
20
- end
21
- end
@@ -1,16 +0,0 @@
1
- module Braintree
2
- class Transaction
3
- class CoinbaseDetails
4
- include BaseModule
5
-
6
- attr_reader :user_id
7
- attr_reader :user_email
8
- attr_reader :user_name
9
- attr_reader :token
10
-
11
- def initialize(attributes)
12
- set_instance_variables_from_hash attributes unless attributes.nil?
13
- end
14
- end
15
- end
16
- end
@@ -1,19 +0,0 @@
1
- module Braintree
2
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
3
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
4
- class Transaction
5
- class IdealPaymentDetails # :nodoc:
6
- include BaseModule
7
-
8
- attr_reader :bic
9
- attr_reader :ideal_payment_id
10
- attr_reader :ideal_transaction_id
11
- attr_reader :image_url
12
- attr_reader :masked_iban
13
-
14
- def initialize(attributes)
15
- set_instance_variables_from_hash attributes unless attributes.nil?
16
- end
17
- end
18
- end
19
- end
@@ -1,47 +0,0 @@
1
- module Braintree
2
- class Transaction
3
- class MasterpassCardDetails # :nodoc:
4
- include BaseModule
5
-
6
- attr_reader :bin
7
- attr_reader :card_type
8
- attr_reader :cardholder_name
9
- attr_reader :commercial
10
- attr_reader :country_of_issuance
11
- attr_reader :customer_location
12
- attr_reader :debit
13
- attr_reader :durbin_regulated
14
- attr_reader :expiration_month
15
- attr_reader :expiration_year
16
- attr_reader :healthcare
17
- attr_reader :image_url
18
- attr_reader :issuing_bank
19
- attr_reader :last_4
20
- attr_reader :payroll
21
- attr_reader :prepaid
22
- attr_reader :product_id
23
- attr_reader :token
24
-
25
- def initialize(attributes)
26
- set_instance_variables_from_hash attributes unless attributes.nil?
27
- end
28
-
29
- def expiration_date
30
- "#{expiration_month}/#{expiration_year}"
31
- end
32
-
33
- def inspect
34
- attr_order = [:token, :bin, :last_4, :card_type, :expiration_date, :cardholder_name, :customer_location, :prepaid,
35
- :healthcare, :durbin_regulated, :debit, :commercial, :payroll, :product_id, :country_of_issuance, :issuing_bank, :image_url]
36
- formatted_attrs = attr_order.map do |attr|
37
- "#{attr}: #{send(attr).inspect}"
38
- end
39
- "#<#{formatted_attrs.join(", ")}>"
40
- end
41
-
42
- def masked_number
43
- "#{bin}******#{last_4}"
44
- end
45
- end
46
- end
47
- end
@@ -1,40 +0,0 @@
1
- module Braintree
2
- module TransparentRedirect
3
- module Kind # :nodoc:
4
- CreateCustomer = "create_customer"
5
- UpdateCustomer = "update_customer"
6
- CreatePaymentMethod = "create_payment_method"
7
- UpdatePaymentMethod = "update_payment_method"
8
- CreateTransaction = "create_transaction"
9
- end
10
-
11
- def self.confirm(*args)
12
- Configuration.gateway.transparent_redirect.confirm(*args)
13
- end
14
-
15
- def self.create_credit_card_data(*args)
16
- Configuration.gateway.transparent_redirect.create_credit_card_data(*args)
17
- end
18
-
19
- def self.create_customer_data(*args)
20
- Configuration.gateway.transparent_redirect.create_customer_data(*args)
21
- end
22
-
23
- def self.transaction_data(*args)
24
- Configuration.gateway.transparent_redirect.transaction_data(*args)
25
- end
26
-
27
- def self.update_credit_card_data(*args)
28
- Configuration.gateway.transparent_redirect.update_credit_card_data(*args)
29
- end
30
-
31
- def self.update_customer_data(*args)
32
- Configuration.gateway.transparent_redirect.update_customer_data(*args)
33
- end
34
-
35
- # Returns the URL to which Transparent Redirect Requests should be posted
36
- def self.url
37
- Configuration.gateway.transparent_redirect.url
38
- end
39
- end
40
- end
@@ -1,105 +0,0 @@
1
- module Braintree
2
- class TransparentRedirectGateway # :nodoc
3
- TransparentRedirectKeys = [:redirect_url] # :nodoc:
4
- CreateCustomerSignature = TransparentRedirectKeys + [{:customer => CustomerGateway._create_signature}] # :nodoc:
5
- UpdateCustomerSignature = TransparentRedirectKeys + [:customer_id, {:customer => CustomerGateway._update_signature}] # :nodoc:
6
- TransactionSignature = TransparentRedirectKeys + [{:transaction => TransactionGateway._create_signature}] # :nodoc:
7
- CreateCreditCardSignature = TransparentRedirectKeys + [{:credit_card => CreditCardGateway._create_signature}] # :nodoc:
8
- UpdateCreditCardSignature = TransparentRedirectKeys + [:payment_method_token, {:credit_card => CreditCardGateway._update_signature}] # :nodoc:
9
-
10
- def initialize(gateway)
11
- @gateway = gateway
12
- @config = gateway.config
13
- @config.assert_has_access_token_or_keys
14
- end
15
-
16
- def confirm(query_string)
17
- params = @gateway.transparent_redirect.parse_and_validate_query_string query_string
18
- confirmation_gateway = {
19
- TransparentRedirect::Kind::CreateCustomer => :customer,
20
- TransparentRedirect::Kind::UpdateCustomer => :customer,
21
- TransparentRedirect::Kind::CreatePaymentMethod => :credit_card,
22
- TransparentRedirect::Kind::UpdatePaymentMethod => :credit_card,
23
- TransparentRedirect::Kind::CreateTransaction => :transaction
24
- }[params[:kind]]
25
-
26
- @gateway.send(confirmation_gateway)._do_create("/transparent_redirect_requests/#{params[:id]}/confirm")
27
- end
28
-
29
- def create_credit_card_data(params)
30
- Util.verify_keys(CreateCreditCardSignature, params)
31
- params[:kind] = TransparentRedirect::Kind::CreatePaymentMethod
32
- _data(params)
33
- end
34
-
35
- def create_customer_data(params)
36
- Util.verify_keys(CreateCustomerSignature, params)
37
- params[:kind] = TransparentRedirect::Kind::CreateCustomer
38
- _data(params)
39
- end
40
-
41
- def parse_and_validate_query_string(query_string) # :nodoc:
42
- params = Util.symbolize_keys(Util.parse_query_string(query_string))
43
- query_string_without_hash = query_string.split("&").reject{|param| param =~ /\Ahash=/}.join("&")
44
- decoded_query_string_without_hash = Util.url_decode(query_string_without_hash)
45
- encoded_query_string_without_hash = Util.url_encode(query_string_without_hash)
46
-
47
- if params[:http_status] == nil
48
- raise UnexpectedError, "expected query string to have an http_status param"
49
- elsif params[:http_status] != '200'
50
- Util.raise_exception_for_status_code(params[:http_status], params[:bt_message])
51
- end
52
-
53
- query_strings_without_hash = [query_string_without_hash, encoded_query_string_without_hash, decoded_query_string_without_hash]
54
-
55
- if query_strings_without_hash.any? { |query_string| @config.signature_service.hash(query_string) == params[:hash] }
56
- params
57
- else
58
- raise ForgedQueryString
59
- end
60
- end
61
-
62
- def transaction_data(params)
63
- Util.verify_keys(TransactionSignature, params)
64
- params[:kind] = TransparentRedirect::Kind::CreateTransaction
65
- transaction_type = params[:transaction] && params[:transaction][:type]
66
- unless %w[sale credit].include?(transaction_type)
67
- raise ArgumentError, "expected transaction[type] of sale or credit, was: #{transaction_type.inspect}"
68
- end
69
- _data(params)
70
- end
71
-
72
- def update_credit_card_data(params)
73
- Util.verify_keys(UpdateCreditCardSignature, params)
74
- unless params[:payment_method_token]
75
- raise ArgumentError, "expected params to contain :payment_method_token of payment method to update"
76
- end
77
- params[:kind] = TransparentRedirect::Kind::UpdatePaymentMethod
78
- _data(params)
79
- end
80
-
81
- def update_customer_data(params)
82
- Util.verify_keys(UpdateCustomerSignature, params)
83
- unless params[:customer_id]
84
- raise ArgumentError, "expected params to contain :customer_id of customer to update"
85
- end
86
- params[:kind] = TransparentRedirect::Kind::UpdateCustomer
87
- _data(params)
88
- end
89
-
90
- def url
91
- "#{@config.base_merchant_url}/transparent_redirect_requests"
92
- end
93
-
94
- def _data(params) # :nodoc:
95
- raise ArgumentError, "expected params to contain :redirect_url" unless params[:redirect_url]
96
-
97
- @config.signature_service.sign(params.merge(
98
- :api_version => @config.api_version,
99
- :time => Time.now.utc.strftime("%Y%m%d%H%M%S"),
100
- :public_key => @config.public_key
101
- ))
102
- end
103
- end
104
- end
105
-
@@ -1,71 +0,0 @@
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
71
-