braintree 2.102.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
-