braintree 4.1.0 → 4.5.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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/apple_pay_card.rb +9 -0
  3. data/lib/braintree/error_codes.rb +2 -0
  4. data/lib/braintree/google_pay_card.rb +9 -0
  5. data/lib/braintree/http.rb +1 -0
  6. data/lib/braintree/local_payment_expired.rb +21 -0
  7. data/lib/braintree/local_payment_funded.rb +22 -0
  8. data/lib/braintree/payment_method_nonce.rb +6 -3
  9. data/lib/braintree/plan.rb +20 -0
  10. data/lib/braintree/plan_gateway.rb +100 -0
  11. data/lib/braintree/successful_result.rb +1 -0
  12. data/lib/braintree/transaction/paypal_details.rb +2 -0
  13. data/lib/braintree/transaction_gateway.rb +2 -2
  14. data/lib/braintree/transaction_review.rb +18 -0
  15. data/lib/braintree/version.rb +1 -1
  16. data/lib/braintree/webhook_notification.rb +9 -0
  17. data/lib/braintree/webhook_testing_gateway.rb +46 -2
  18. data/lib/braintree.rb +2 -0
  19. data/spec/integration/braintree/customer_spec.rb +27 -0
  20. data/spec/integration/braintree/merchant_account_spec.rb +3 -3
  21. data/spec/integration/braintree/payment_method_nonce_spec.rb +2 -0
  22. data/spec/integration/braintree/payment_method_spec.rb +27 -0
  23. data/spec/integration/braintree/plan_spec.rb +82 -0
  24. data/spec/integration/braintree/transaction_spec.rb +44 -0
  25. data/spec/spec_helper.rb +1 -0
  26. data/spec/unit/braintree/http_spec.rb +2 -0
  27. data/spec/unit/braintree/local_payment_expired_spec.rb +24 -0
  28. data/spec/unit/braintree/local_payment_funded_spec.rb +34 -0
  29. data/spec/unit/braintree/payment_method_nonce_spec.rb +40 -0
  30. data/spec/unit/braintree/transaction/paypal_details_spec.rb +4 -0
  31. data/spec/unit/braintree/transaction_spec.rb +3 -3
  32. data/spec/unit/braintree/webhook_notification_spec.rb +52 -1
  33. metadata +9 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d934c307cf9a97cf867edc42477230eba5680d7183c73ce691aef287abbb01d6
4
- data.tar.gz: b817ec7febb2c2e050c2ed3a19820e67b93890a34211fc5364ba4fc0f1487778
3
+ metadata.gz: 34698c59add2b3613d0c75e58d2d9d8ee5f3aecdd6ef85c79e303211199b4fa8
4
+ data.tar.gz: 933cf9e7d93aec94ba227fef1f03e4f245b7e0e4512b57ebf96ddd9ffef89cab
5
5
  SHA512:
6
- metadata.gz: d527fd7a32ac2240f108531ad040d6525ecc7a87fd23e18b5de3e4674ebc1daf7197ccb260ecad6e58bd6ed77132aac25249ed90f1d3e630054c3995eb28171e
7
- data.tar.gz: 2e8ff42991a0120a0aef55705780b0659576b550cb62c6f499f44011c5b7bab441d64f3d6ad3ee27dd6f16b2787e24f849d01d8429c7bcf415d356e621cee81f
6
+ metadata.gz: d44a8addd727ea6efe503a33c275956bf0a359abe402ee42fff43785b48e30a84a29ecf6e6cbf8aacb080e8562e553f6c9c2424878575815f08cd563647e6762
7
+ data.tar.gz: 4b631596ff355ee26deceac5c37b61e66b0c5cf5336392120df61802be53b276cf2ebf9d93c6fb64dae3bea06d3dcb925644620aa829afaf7d2382328e7b2152
@@ -12,15 +12,24 @@ module Braintree
12
12
 
13
13
  attr_reader :bin
14
14
  attr_reader :card_type
15
+ attr_reader :commercial
16
+ attr_reader :country_of_issuance
15
17
  attr_reader :created_at
16
18
  attr_reader :customer_id
19
+ attr_reader :debit
17
20
  attr_reader :default
21
+ attr_reader :durbin_regulated
18
22
  attr_reader :expiration_month
19
23
  attr_reader :expiration_year
20
24
  attr_reader :expired
25
+ attr_reader :healthcare
21
26
  attr_reader :image_url
27
+ attr_reader :issuing_bank
22
28
  attr_reader :last_4
23
29
  attr_reader :payment_instrument_name
30
+ attr_reader :payroll
31
+ attr_reader :prepaid
32
+ attr_reader :product_id
24
33
  attr_reader :source_description
25
34
  attr_reader :subscriptions
26
35
  attr_reader :token
@@ -312,6 +312,7 @@ module Braintree
312
312
  DiscountAmountCannotBeNegative = "915160"
313
313
  DiscountAmountFormatIsInvalid = "915159"
314
314
  DiscountAmountIsTooLarge = "915161"
315
+ ExchangeRateQuoteIdTooLong = "915229"
315
316
  FailedAuthAdjustmentAllowRetry = "95603"
316
317
  FailedAuthAdjustmentHardDecline = "95602"
317
318
  FinalAuthSubmitForSettlementForDifferentAmount = "95601"
@@ -385,6 +386,7 @@ module Braintree
385
386
  SubscriptionStatusMustBePastDue = "91531"
386
387
  TaxAmountCannotBeNegative = "81534"
387
388
  TaxAmountFormatIsInvalid = "81535"
389
+ TaxAmountIsRequiredForAibSwedish = "815224"
388
390
  TaxAmountIsTooLarge = "81536"
389
391
  ThreeDSecureAuthenticationFailed = "81571"
390
392
  ThreeDSecureAuthenticationIdDoesntMatchNonceThreeDSecureAuthentication = "915198"
@@ -3,13 +3,22 @@ module Braintree
3
3
  include BaseModule # :nodoc:
4
4
 
5
5
  attr_reader :bin
6
+ attr_reader :commercial
7
+ attr_reader :country_of_issuance
6
8
  attr_reader :created_at
7
9
  attr_reader :customer_id
10
+ attr_reader :debit
8
11
  attr_reader :default
12
+ attr_reader :durbin_regulated
9
13
  attr_reader :expiration_month
10
14
  attr_reader :expiration_year
11
15
  attr_reader :google_transaction_id
16
+ attr_reader :healthcare
12
17
  attr_reader :image_url
18
+ attr_reader :issuing_bank
19
+ attr_reader :payroll
20
+ attr_reader :prepaid
21
+ attr_reader :product_id
13
22
  attr_reader :source_card_last_4
14
23
  attr_reader :source_card_type
15
24
  attr_reader :source_description
@@ -188,6 +188,7 @@ module Braintree
188
188
  formatted_xml = input_xml.gsub(/^/, "[Braintree] ")
189
189
  formatted_xml = formatted_xml.gsub(/<number>(.{6}).+?(.{4})<\/number>/m, '<number>\1******\2</number>')
190
190
  formatted_xml = formatted_xml.gsub(/<cvv>.+?<\/cvv>/m, "<cvv>***</cvv>")
191
+ formatted_xml = formatted_xml.gsub(/<encrypted-card-data>.+?<\/encrypted-card-data>/m, "<encrypted-card-data>***</encrypted-card-data>")
191
192
  formatted_xml
192
193
  end
193
194
 
@@ -0,0 +1,21 @@
1
+ module Braintree
2
+ class LocalPaymentExpired
3
+ include BaseModule
4
+
5
+ attr_reader :payment_id
6
+ attr_reader :payment_context_id
7
+
8
+ def initialize(attributes) # :nodoc:
9
+ set_instance_variables_from_hash(attributes)
10
+ end
11
+
12
+ class << self
13
+ protected :new
14
+ end
15
+
16
+ def self._new(*args) # :nodoc:
17
+ self.new(*args)
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,22 @@
1
+ module Braintree
2
+ class LocalPaymentFunded
3
+ include BaseModule
4
+
5
+ attr_reader :payment_id
6
+ attr_reader :payment_context_id
7
+ attr_reader :transaction
8
+
9
+ def initialize(attributes) # :nodoc:
10
+ set_instance_variables_from_hash(attributes)
11
+ @transaction = Transaction._new(Configuration.gateway, transaction)
12
+ end
13
+
14
+ class << self
15
+ protected :new
16
+ end
17
+
18
+ def self._new(*args) # :nodoc:
19
+ self.new(*args)
20
+ end
21
+ end
22
+ end
@@ -15,6 +15,7 @@ module Braintree
15
15
  end
16
16
 
17
17
  attr_reader :bin_data
18
+ attr_reader :default
18
19
  attr_reader :details
19
20
  attr_reader :nonce
20
21
  attr_reader :three_d_secure_info
@@ -23,14 +24,16 @@ module Braintree
23
24
 
24
25
  def initialize(gateway, attributes) # :nodoc:
25
26
  @gateway = gateway
26
- @nonce = attributes.fetch(:nonce)
27
- @type = attributes.fetch(:type)
27
+ set_instance_variables_from_hash(attributes)
28
28
  @details = PaymentMethodNonceDetails.new(attributes[:details]) if attributes[:details]
29
- @authentication_insight = attributes.fetch(:authentication_insight, nil)
30
29
  @three_d_secure_info = ThreeDSecureInfo.new(attributes[:three_d_secure_info]) if attributes[:three_d_secure_info]
31
30
  @bin_data = BinData.new(attributes[:bin_data]) if attributes[:bin_data]
32
31
  end
33
32
 
33
+ def default?
34
+ @default
35
+ end
36
+
34
37
  def to_s # :nodoc:
35
38
  nonce
36
39
  end
@@ -33,6 +33,26 @@ module Braintree
33
33
 
34
34
  class << self
35
35
  protected :new
36
+
37
+ def create(*args)
38
+ Configuration.gateway.plan.create(*args)
39
+ end
40
+
41
+ def create!(*args)
42
+ Configuration.gateway.plan.create!(*args)
43
+ end
44
+
45
+ def find(*args)
46
+ Configuration.gateway.plan.find(*args)
47
+ end
48
+
49
+ def update(*args)
50
+ Configuration.gateway.plan.update(*args)
51
+ end
52
+
53
+ def update!(*args)
54
+ Configuration.gateway.plan.update!(*args)
55
+ end
36
56
  end
37
57
 
38
58
  def self._new(*args)
@@ -1,5 +1,7 @@
1
1
  module Braintree
2
2
  class PlanGateway # :nodoc:
3
+ include BaseModule
4
+
3
5
  def initialize(gateway)
4
6
  @gateway = gateway
5
7
  @config = gateway.config
@@ -13,5 +15,103 @@ module Braintree
13
15
  Plan._new(@gateway, attributes)
14
16
  end
15
17
  end
18
+
19
+ def create(attributes)
20
+ Util.verify_keys(PlanGateway._create_signature, attributes)
21
+ _do_create "/plans", :plan => attributes
22
+ end
23
+
24
+ def create!(*args)
25
+ return_object_or_raise(:plan) { create(*args) }
26
+ end
27
+
28
+ def find(id)
29
+ raise ArgumentError if id.nil? || id.to_s.strip == ""
30
+ response = @config.http.get("#{@config.base_merchant_path}/plans/#{id}")
31
+ Plan._new(@gateway, response[:plan])
32
+ rescue NotFoundError
33
+ raise NotFoundError, "plan with id #{id.inspect} not found"
34
+ end
35
+
36
+ def update(plan_id, attributes)
37
+ Util.verify_keys(PlanGateway._update_signature, attributes)
38
+ response = @config.http.put("#{@config.base_merchant_path}/plans/#{plan_id}", :plan => attributes)
39
+ if response[:plan]
40
+ SuccessfulResult.new(:plan => Plan._new(@gateway, response[:plan]))
41
+ elsif response[:api_error_response]
42
+ ErrorResult.new(@gateway, response[:api_error_response])
43
+ else
44
+ raise UnexpectedError, "expected :plan or :api_error_response"
45
+ end
46
+ end
47
+
48
+ def update!(*args)
49
+ return_object_or_raise(:plan) { update(*args) }
50
+ end
51
+
52
+ def self._create_signature
53
+ [
54
+ :billing_day_of_month,
55
+ :billing_frequency,
56
+ :currency_iso_code,
57
+ :description,
58
+ :id,
59
+ :merchant_id,
60
+ :name,
61
+ :number_of_billing_cycles,
62
+ :price,
63
+ :trial_duration,
64
+ :trial_duration_unit,
65
+ :trial_period
66
+ ] + _add_on_discount_signature
67
+ end
68
+
69
+ def self._update_signature
70
+ [
71
+ :billing_day_of_month,
72
+ :billing_frequency,
73
+ :currency_iso_code,
74
+ :description,
75
+ :id,
76
+ :merchant_id,
77
+ :name,
78
+ :number_of_billing_cycles,
79
+ :price,
80
+ :trial_duration,
81
+ :trial_duration_unit,
82
+ :trial_period
83
+ ] + _add_on_discount_signature
84
+ end
85
+
86
+ def self._add_on_discount_signature
87
+ [
88
+ {
89
+ :add_ons => [
90
+ {:add => [:amount, :inherited_from_id, :never_expires, :number_of_billing_cycles, :quantity]},
91
+ {:update => [:amount, :existing_id, :never_expires, :number_of_billing_cycles, :quantity]},
92
+ {:remove => [:_any_key_]}
93
+ ]
94
+ },
95
+ {
96
+ :discounts => [
97
+ {:add => [:amount, :inherited_from_id, :never_expires, :number_of_billing_cycles, :quantity]},
98
+ {:update => [:amount, :existing_id, :never_expires, :number_of_billing_cycles, :quantity]},
99
+ {:remove => [:_any_key_]}
100
+ ]
101
+ }
102
+ ]
103
+ end
104
+
105
+ def _do_create(path, params) # :nodoc:
106
+ response = @config.http.post("#{@config.base_merchant_path}#{path}", params)
107
+ if response[:plan]
108
+ SuccessfulResult.new(:plan => Plan._new(@gateway, response[:plan]))
109
+ elsif response[:errors]
110
+ ErrorResult.new(@gateway, response[:errors])
111
+ else
112
+ raise UnexpectedError, "expected :plan or :errors"
113
+ end
114
+ end
16
115
  end
17
116
  end
117
+
@@ -16,6 +16,7 @@ module Braintree
16
16
  attr_reader :payment_method
17
17
  attr_reader :payment_method_nonce
18
18
  attr_reader :paypal_account
19
+ attr_reader :plan
19
20
  attr_reader :settlement_batch_summary
20
21
  attr_reader :subscription
21
22
  attr_reader :supported_networks
@@ -24,6 +24,8 @@ module Braintree
24
24
  attr_reader :refund_from_transaction_fee_currency_iso_code
25
25
  attr_reader :refund_id
26
26
  attr_reader :seller_protection_status
27
+ attr_reader :tax_id
28
+ attr_reader :tax_id_type
27
29
  attr_reader :token
28
30
  attr_reader :transaction_fee_amount
29
31
  attr_reader :transaction_fee_currency_iso_code
@@ -61,7 +61,7 @@ module Braintree
61
61
  end
62
62
 
63
63
  def find(id)
64
- raise ArgumentError if id.nil? || id.strip.to_s == ""
64
+ raise ArgumentError, "id can not be empty" if id.nil? || id.strip.to_s == ""
65
65
  response = @config.http.get("#{@config.base_merchant_path}/transactions/#{id}")
66
66
  Transaction._new(@gateway, response[:transaction])
67
67
  rescue NotFoundError
@@ -192,7 +192,7 @@ module Braintree
192
192
  :shared_shipping_address_id, :shipping_address_id, :shipping_amount,
193
193
  :ships_from_postal_code, :tax_amount, :tax_exempt, :three_d_secure_authentication_id,
194
194
  :three_d_secure_token, :transaction_source, :type, :venmo_sdk_payment_method_code,
195
- :sca_exemption, :currency_iso_code,
195
+ :sca_exemption, :currency_iso_code, :exchange_rate_quote_id,
196
196
  {: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]},
197
197
  {:risk_data => [:customer_browser, :customer_device_id, :customer_ip, :customer_location_zip, :customer_tenure]},
198
198
  {:credit_card => [:token, :cardholder_name, :cvv, :expiration_date, :expiration_month, :expiration_year, :number, {:payment_reader_card_details => [:encrypted_card_data, :key_serial_number]}]},
@@ -0,0 +1,18 @@
1
+ module Braintree
2
+ class TransactionReview
3
+ include BaseModule
4
+
5
+ attr_reader :transaction_id, :decision, :reviewer_email, :reviewer_note, :reviewer_time
6
+
7
+ def initialize(attributes)
8
+ set_instance_variables_from_hash(attributes)
9
+ end
10
+
11
+ class << self
12
+ protected :new
13
+ def _new(*args) # :nodoc:
14
+ self.new(*args)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 4
4
- Minor = 1
4
+ Minor = 5
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
@@ -28,6 +28,8 @@ module Braintree
28
28
  GrantedPaymentMethodRevoked = "granted_payment_method_revoked"
29
29
 
30
30
  LocalPaymentCompleted = "local_payment_completed"
31
+ LocalPaymentExpired = "local_payment_expired"
32
+ LocalPaymentFunded = "local_payment_funded"
31
33
  LocalPaymentReversed = "local_payment_reversed"
32
34
 
33
35
  OAuthAccessRevoked = "oauth_access_revoked"
@@ -52,6 +54,7 @@ module Braintree
52
54
  SubMerchantAccountDeclined = "sub_merchant_account_declined"
53
55
 
54
56
  TransactionDisbursed = "transaction_disbursed"
57
+ TransactionReviewed = "transaction_reviewed"
55
58
  TransactionSettlementDeclined = "transaction_settlement_declined"
56
59
  TransactionSettled = "transaction_settled"
57
60
  end
@@ -65,6 +68,8 @@ module Braintree
65
68
  attr_reader :revoked_payment_method_metadata
66
69
  attr_reader :kind
67
70
  attr_reader :local_payment_completed
71
+ attr_reader :local_payment_expired
72
+ attr_reader :local_payment_funded
68
73
  attr_reader :local_payment_reversed
69
74
  attr_reader :oauth_access_revocation
70
75
  attr_reader :partner_merchant
@@ -72,6 +77,7 @@ module Braintree
72
77
  attr_reader :subscription
73
78
  attr_reader :timestamp
74
79
  attr_reader :transaction
80
+ attr_reader :transaction_review
75
81
 
76
82
  def self.parse(*args)
77
83
  Configuration.gateway.webhook_notification.parse(*args)
@@ -90,6 +96,7 @@ module Braintree
90
96
  @oauth_access_revocation = OpenStruct.new(@subject[:oauth_application_revocation]) if @subject.has_key?(:oauth_application_revocation)
91
97
  @subscription = Subscription._new(gateway, @subject[:subscription]) if @subject.has_key?(:subscription)
92
98
  @transaction = Transaction._new(gateway, @subject[:transaction]) if @subject.has_key?(:transaction)
99
+ @transaction_review = OpenStruct.new(@subject[:transaction_review]) if @subject.has_key?(:transaction_review)
93
100
  @disbursement = Disbursement._new(gateway, @subject[:disbursement]) if @subject.has_key?(:disbursement)
94
101
  @dispute = Dispute._new(@subject[:dispute]) if @subject.has_key?(:dispute)
95
102
  @account_updater_daily_report = AccountUpdaterDailyReport._new(@subject[:account_updater_daily_report]) if @subject.has_key?(:account_updater_daily_report)
@@ -98,6 +105,8 @@ module Braintree
98
105
  @granted_payment_instrument_update = GrantedPaymentInstrumentUpdate._new(@subject[:granted_payment_instrument_update]) if @subject.has_key?(:granted_payment_instrument_update)
99
106
  @revoked_payment_method_metadata = RevokedPaymentMethodMetadata._new(gateway, @subject) if [Kind::GrantedPaymentInstrumentRevoked, Kind::PaymentMethodRevokedByCustomer, Kind::GrantedPaymentMethodRevoked].include?(@kind)
100
107
  @local_payment_completed = LocalPaymentCompleted._new(@subject[:local_payment]) if @subject.has_key?(:local_payment) && Kind::LocalPaymentCompleted == @kind
108
+ @local_payment_expired = LocalPaymentExpired._new(@subject[:local_payment_expired]) if @subject.has_key?(:local_payment_expired) && Kind::LocalPaymentExpired == @kind
109
+ @local_payment_funded = LocalPaymentFunded._new(@subject[:local_payment_funded]) if @subject.has_key?(:local_payment_funded) && Kind::LocalPaymentFunded == @kind
101
110
  @local_payment_reversed = LocalPaymentReversed._new(@subject[:local_payment_reversed]) if @subject.has_key?(:local_payment_reversed) && Kind::LocalPaymentReversed == @kind
102
111
  end
103
112
 
@@ -60,6 +60,8 @@ module Braintree
60
60
  _merchant_account_declined_sample_xml(id)
61
61
  when Braintree::WebhookNotification::Kind::TransactionDisbursed
62
62
  _transaction_disbursed_sample_xml(id)
63
+ when Braintree::WebhookNotification::Kind::TransactionReviewed
64
+ _transaction_reviewed_sample_xml(id)
63
65
  when Braintree::WebhookNotification::Kind::TransactionSettled
64
66
  _transaction_settled_sample_xml(id)
65
67
  when Braintree::WebhookNotification::Kind::TransactionSettlementDeclined
@@ -88,8 +90,12 @@ module Braintree
88
90
  _payment_method_revoked_by_customer_sample_xml(id)
89
91
  when Braintree::WebhookNotification::Kind::LocalPaymentCompleted
90
92
  _local_payment_completed_sample_xml(id)
93
+ when Braintree::WebhookNotification::Kind::LocalPaymentExpired
94
+ _local_payment_expired_sample_xml
95
+ when Braintree::WebhookNotification::Kind::LocalPaymentFunded
96
+ _local_payment_funded_sample_xml(id)
91
97
  when Braintree::WebhookNotification::Kind::LocalPaymentReversed
92
- _local_payment_reversed_sample_xml(id)
98
+ _local_payment_reversed_sample_xml
93
99
  else
94
100
  _subscription_sample_xml(id)
95
101
  end
@@ -244,6 +250,19 @@ module Braintree
244
250
  XML
245
251
  end
246
252
 
253
+ def _transaction_reviewed_sample_xml(id)
254
+
255
+ <<-XML
256
+ <transaction-review>
257
+ <transaction-id>my_id</transaction-id>
258
+ <decision>decision</decision>
259
+ <reviewer-email>hey@girl.com</reviewer-email>
260
+ <reviewer-note>i reviewed this</reviewer-note>
261
+ <reviewed-time type="datetime">2017-06-16T20:44:41Z</reviewed-time>
262
+ </transaction-review>
263
+ XML
264
+ end
265
+
247
266
  def _transaction_settled_sample_xml(id)
248
267
  <<-XML
249
268
  <transaction>
@@ -935,10 +954,35 @@ module Braintree
935
954
  XML
936
955
  end
937
956
 
938
- def _local_payment_reversed_sample_xml(id)
957
+ def _local_payment_expired_sample_xml
958
+ <<-XML
959
+ <local-payment-expired>
960
+ <payment-id>PAY-XYZ123</payment-id>
961
+ <payment-context-id>cG5b=</payment-context-id>
962
+ </local-payment-expired>
963
+ XML
964
+ end
965
+
966
+ def _local_payment_funded_sample_xml(id)
967
+ <<-XML
968
+ <local-payment-funded>
969
+ <payment-id>PAY-XYZ123</payment-id>
970
+ <payment-context-id>cG5b=</payment-context-id>
971
+ <transaction>
972
+ <id>#{id}</id>
973
+ <status>settled</status>
974
+ <amount>49.99</amount>
975
+ <order-id>order4567</order-id>
976
+ </transaction>
977
+ </local-payment-funded>
978
+ XML
979
+ end
980
+
981
+ def _local_payment_reversed_sample_xml
939
982
  <<-XML
940
983
  <local-payment-reversed>
941
984
  <payment-id>PAY-XYZ123</payment-id>
985
+ <payment-context-id>cG5b=</payment-context-id>
942
986
  </local-payment-reversed>
943
987
  XML
944
988
  end
data/lib/braintree.rb CHANGED
@@ -73,6 +73,8 @@ require "braintree/graphql_client"
73
73
  require "braintree/google_pay_card"
74
74
  require "braintree/local_payment_completed"
75
75
  require "braintree/local_payment_reversed"
76
+ require "braintree/local_payment_expired"
77
+ require "braintree/local_payment_funded"
76
78
  require "braintree/transaction/local_payment_details"
77
79
  require "braintree/merchant"
78
80
  require "braintree/merchant_gateway"
@@ -1021,6 +1021,15 @@ describe Braintree::Customer do
1021
1021
  apple_pay_card.token.should_not be_nil
1022
1022
  apple_pay_card.expiration_year.should_not be_nil
1023
1023
  apple_pay_card.payment_instrument_name.should == "AmEx 41002"
1024
+ apple_pay_card.commercial.should_not be_nil
1025
+ apple_pay_card.country_of_issuance.should_not be_nil
1026
+ apple_pay_card.debit.should_not be_nil
1027
+ apple_pay_card.durbin_regulated.should_not be_nil
1028
+ apple_pay_card.healthcare.should_not be_nil
1029
+ apple_pay_card.issuing_bank.should_not be_nil
1030
+ apple_pay_card.payroll.should_not be_nil
1031
+ apple_pay_card.prepaid.should_not be_nil
1032
+ apple_pay_card.product_id.should_not be_nil
1024
1033
  end
1025
1034
 
1026
1035
  it "returns associated google pay proxy cards" do
@@ -1037,6 +1046,15 @@ describe Braintree::Customer do
1037
1046
  google_pay_card.token.should_not be_nil
1038
1047
  google_pay_card.expiration_year.should_not be_nil
1039
1048
  google_pay_card.is_network_tokenized?.should == false
1049
+ google_pay_card.commercial.should_not be_nil
1050
+ google_pay_card.country_of_issuance.should_not be_nil
1051
+ google_pay_card.debit.should_not be_nil
1052
+ google_pay_card.durbin_regulated.should_not be_nil
1053
+ google_pay_card.healthcare.should_not be_nil
1054
+ google_pay_card.issuing_bank.should_not be_nil
1055
+ google_pay_card.payroll.should_not be_nil
1056
+ google_pay_card.prepaid.should_not be_nil
1057
+ google_pay_card.product_id.should_not be_nil
1040
1058
  end
1041
1059
 
1042
1060
  it "returns associated google pay network tokens" do
@@ -1053,6 +1071,15 @@ describe Braintree::Customer do
1053
1071
  google_pay_card.token.should_not be_nil
1054
1072
  google_pay_card.expiration_year.should_not be_nil
1055
1073
  google_pay_card.is_network_tokenized?.should == true
1074
+ google_pay_card.commercial.should_not be_nil
1075
+ google_pay_card.country_of_issuance.should_not be_nil
1076
+ google_pay_card.debit.should_not be_nil
1077
+ google_pay_card.durbin_regulated.should_not be_nil
1078
+ google_pay_card.healthcare.should_not be_nil
1079
+ google_pay_card.issuing_bank.should_not be_nil
1080
+ google_pay_card.payroll.should_not be_nil
1081
+ google_pay_card.prepaid.should_not be_nil
1082
+ google_pay_card.product_id.should_not be_nil
1056
1083
  end
1057
1084
 
1058
1085
  it "returns associated venmo accounts" do
@@ -41,7 +41,7 @@ VALID_APPLICATION_PARAMS = {
41
41
  :business => {
42
42
  :legal_name => "Joe's Bloggs",
43
43
  :dba_name => "Joe's Junkyard",
44
- :tax_id => "123456789",
44
+ :tax_id => "423456789",
45
45
  :address => {
46
46
  :street_address => "456 Fake St",
47
47
  :postal_code => "48104",
@@ -371,7 +371,7 @@ describe Braintree::MerchantAccount do
371
371
  params[:individual][:address][:postal_code] = "60622"
372
372
  params[:business][:dba_name] = "James's Bloggs"
373
373
  params[:business][:legal_name] = "James's Bloggs Inc"
374
- params[:business][:tax_id] = "123456789"
374
+ params[:business][:tax_id] = "423456789"
375
375
  params[:business][:address][:street_address] = "999 Fake St"
376
376
  params[:business][:address][:locality] = "Miami"
377
377
  params[:business][:address][:region] = "FL"
@@ -397,7 +397,7 @@ describe Braintree::MerchantAccount do
397
397
  result.merchant_account.individual_details.address_details.postal_code.should == "60622"
398
398
  result.merchant_account.business_details.dba_name.should == "James's Bloggs"
399
399
  result.merchant_account.business_details.legal_name.should == "James's Bloggs Inc"
400
- result.merchant_account.business_details.tax_id.should == "123456789"
400
+ result.merchant_account.business_details.tax_id.should == "423456789"
401
401
  result.merchant_account.business_details.address_details.street_address.should == "999 Fake St"
402
402
  result.merchant_account.business_details.address_details.locality.should == "Miami"
403
403
  result.merchant_account.business_details.address_details.region.should == "FL"
@@ -32,6 +32,7 @@ describe Braintree::PaymentMethodNonce do
32
32
  result.payment_method_nonce.should_not be_nil
33
33
  result.payment_method_nonce.nonce.should_not be_nil
34
34
  result.payment_method_nonce.details.should_not be_nil
35
+ result.payment_method_nonce.default?.should be_truthy
35
36
  end
36
37
 
37
38
  it "correctly raises and exception for a non existent token" do
@@ -67,6 +68,7 @@ describe Braintree::PaymentMethodNonce do
67
68
  payment_method_nonce.should_not be_nil
68
69
  payment_method_nonce.nonce.should_not be_nil
69
70
  payment_method_nonce.details.should_not be_nil
71
+ payment_method_nonce.default?.should be_truthy
70
72
  end
71
73
  end
72
74
 
@@ -99,6 +99,15 @@ describe Braintree::PaymentMethod do
99
99
  apple_pay_card.expiration_month.to_i.should > 0
100
100
  apple_pay_card.expiration_year.to_i.should > 0
101
101
  apple_pay_card.customer_id.should == customer.id
102
+ apple_pay_card.commercial.should_not be_nil
103
+ apple_pay_card.country_of_issuance.should_not be_nil
104
+ apple_pay_card.debit.should_not be_nil
105
+ apple_pay_card.durbin_regulated.should_not be_nil
106
+ apple_pay_card.healthcare.should_not be_nil
107
+ apple_pay_card.issuing_bank.should_not be_nil
108
+ apple_pay_card.payroll.should_not be_nil
109
+ apple_pay_card.prepaid.should_not be_nil
110
+ apple_pay_card.product_id.should_not be_nil
102
111
  end
103
112
 
104
113
  it "creates a payment method from a fake google pay proxy card nonce" do
@@ -127,6 +136,15 @@ describe Braintree::PaymentMethod do
127
136
  google_pay_card.google_transaction_id.should == "google_transaction_id"
128
137
  google_pay_card.source_description.should == "Discover 1111"
129
138
  google_pay_card.customer_id.should == customer.id
139
+ google_pay_card.commercial.should_not be_nil
140
+ google_pay_card.country_of_issuance.should_not be_nil
141
+ google_pay_card.debit.should_not be_nil
142
+ google_pay_card.durbin_regulated.should_not be_nil
143
+ google_pay_card.healthcare.should_not be_nil
144
+ google_pay_card.issuing_bank.should_not be_nil
145
+ google_pay_card.payroll.should_not be_nil
146
+ google_pay_card.prepaid.should_not be_nil
147
+ google_pay_card.product_id.should_not be_nil
130
148
  end
131
149
 
132
150
  it "creates a payment method from a google pay network token nonce" do
@@ -155,6 +173,15 @@ describe Braintree::PaymentMethod do
155
173
  google_pay_card.google_transaction_id.should == "google_transaction_id"
156
174
  google_pay_card.source_description.should == "MasterCard 4444"
157
175
  google_pay_card.customer_id.should == customer.id
176
+ google_pay_card.commercial.should_not be_nil
177
+ google_pay_card.country_of_issuance.should_not be_nil
178
+ google_pay_card.debit.should_not be_nil
179
+ google_pay_card.durbin_regulated.should_not be_nil
180
+ google_pay_card.healthcare.should_not be_nil
181
+ google_pay_card.issuing_bank.should_not be_nil
182
+ google_pay_card.payroll.should_not be_nil
183
+ google_pay_card.prepaid.should_not be_nil
184
+ google_pay_card.product_id.should_not be_nil
158
185
  end
159
186
 
160
187
  it "creates a payment method from venmo account nonce" do
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
2
3
 
3
4
  describe Braintree::Plan do
4
5
 
@@ -48,6 +49,87 @@ describe Braintree::Plan do
48
49
  end
49
50
  end
50
51
 
52
+ describe "self.create" do
53
+ let(:attributes) do
54
+ {
55
+ :billing_day_of_month => 12,
56
+ :billing_frequency => 1,
57
+ :currency_iso_code => "USD",
58
+ :description => "description on create",
59
+ :name => "my new plan name",
60
+ :number_of_billing_cycles => 1,
61
+ :price => "9.99",
62
+ :trial_period => false
63
+ }
64
+
65
+ it "is successful with given params" do
66
+ result = Braintree::Plan.create(attributes)
67
+ expect(result.success?).to be_truthy
68
+ expect(result.plan.billing_day_of_month).to eq 12
69
+ expect(result.plan.description).to eq "description on create"
70
+ expect(result.plan.name).to eq "my new plan name"
71
+ expect(result.plan.price).to eq "9.99"
72
+ expect(result.plan.billing_frequency).to eq 1
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "self.find" do
78
+ it "finds a plan" do
79
+ plan = Braintree::Plan.create(
80
+ :billing_day_of_month => 12,
81
+ :billing_frequency => 1,
82
+ :currency_iso_code => "USD",
83
+ :description => "description on create",
84
+ :name => "my new plan name",
85
+ :number_of_billing_cycles => 1,
86
+ :price => "9.99",
87
+ :trial_period => false,
88
+ ).plan
89
+
90
+ found_plan = Braintree::Plan.find(plan.id)
91
+ expect(found_plan.name).to eq plan.name
92
+ end
93
+
94
+ it "raises Braintree::NotFoundError if it cannot find" do
95
+ expect {
96
+ Braintree::Plan.find("noSuchPlan")
97
+ }.to raise_error(Braintree::NotFoundError, 'plan with id "noSuchPlan" not found')
98
+ end
99
+ end
100
+
101
+ describe "self.update!" do
102
+ before(:each) do
103
+ @plan = Braintree::Plan.create(
104
+ :billing_day_of_month => 12,
105
+ :billing_frequency => 1,
106
+ :currency_iso_code => "USD",
107
+ :description => "description on create",
108
+ :name => "my new plan name",
109
+ :number_of_billing_cycles => 1,
110
+ :price => "9.99",
111
+ :trial_period => false,
112
+ ).plan
113
+ end
114
+
115
+ it "returns the updated plan if valid" do
116
+ new_id = rand(36**9).to_s(36)
117
+ plan = Braintree::Plan.update!(@plan.id,
118
+ :name => "updated name",
119
+ :price => 99.88,
120
+ )
121
+
122
+ expect(plan.name).to eq "updated name"
123
+ expect(plan.price).to eq BigDecimal("99.88")
124
+ end
125
+
126
+ it "raises a ValidationsFailed if invalid" do
127
+ expect do
128
+ Braintree::Plan.update!(@plan.id, :number_of_billing_cycles => "number of billing cycles")
129
+ end.to raise_error(Braintree::ValidationsFailed)
130
+ end
131
+ end
132
+
51
133
  def create_plan_for_tests(attributes)
52
134
  config = Braintree::Configuration.gateway.config
53
135
  config.http.post("#{config.base_merchant_path}/plans/create_plan_for_tests", :plan => attributes)
@@ -999,6 +999,34 @@ describe Braintree::Transaction do
999
999
  result.transaction.credit_card_details.expiration_date.should == "05/2011"
1000
1000
  end
1001
1001
 
1002
+ it "accepts exchange_rate_quote_id" do
1003
+ result = Braintree::Transaction.create(
1004
+ :type => "sale",
1005
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1006
+ :credit_card => {
1007
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1008
+ :expiration_date => "05/2009"
1009
+ },
1010
+ :exchange_rate_quote_id => "dummyExchangeRateQuoteId-Brainree-Ruby",
1011
+ )
1012
+ result.success?.should == true
1013
+ result.transaction.credit_card_details.expiration_date.should == "05/2009"
1014
+ end
1015
+
1016
+ it "returns an error if provided invalid exchange_rate_quote_id" do
1017
+ result = Braintree::Transaction.create(
1018
+ :type => "sale",
1019
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1020
+ :credit_card => {
1021
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1022
+ :expiration_date => "05/2009"
1023
+ },
1024
+ :exchange_rate_quote_id => "a" * 4010,
1025
+ )
1026
+ result.success?.should == false
1027
+ result.errors.for(:transaction).on(:exchange_rate_quote_id)[0].code.should == Braintree::ErrorCodes::Transaction::ExchangeRateQuoteIdTooLong
1028
+ end
1029
+
1002
1030
  it "returns some error if customer_id is invalid" do
1003
1031
  result = Braintree::Transaction.create(
1004
1032
  :type => "sale",
@@ -5058,6 +5086,22 @@ describe Braintree::Transaction do
5058
5086
  result.errors.for(:transaction).on(:currency_iso_code)[0].code.should == Braintree::ErrorCodes::Transaction::CurrencyCodeNotSupportedByMerchantAccount
5059
5087
  end
5060
5088
 
5089
+ it "validates tax_amount for Aib domestic sweden transaction and returns error" do
5090
+ params = {
5091
+ :transaction => {
5092
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
5093
+ :merchant_account_id => SpecHelper::AibSwedenMaMerchantAccountId,
5094
+ :credit_card => {
5095
+ :number => Braintree::Test::CreditCardNumbers::Visa,
5096
+ :expiration_date => "05/2030"
5097
+ }
5098
+ }
5099
+ }
5100
+ result = Braintree::Transaction.sale(params[:transaction])
5101
+ result.success?.should == false
5102
+ result.errors.for(:transaction).on(:tax_amount)[0].code.should == Braintree::ErrorCodes::Transaction::TaxAmountIsRequiredForAibSwedish
5103
+ end
5104
+
5061
5105
  it "skips advanced fraud checking if transaction[options][skip_advanced_fraud_checking] is set to true" do
5062
5106
  with_advanced_fraud_kount_integration_merchant do
5063
5107
  result = Braintree::Transaction.sale(
data/spec/spec_helper.rb CHANGED
@@ -42,6 +42,7 @@ unless defined?(SPEC_HELPER_LOADED)
42
42
  HiperBRLMerchantAccountId = "hiper_brl"
43
43
  CardProcessorBRLMerchantAccountId = "card_processor_brl"
44
44
  FakeFirstDataMerchantAccountId = "fake_first_data_merchant_account"
45
+ AibSwedenMaMerchantAccountId = "aib_swe_ma"
45
46
 
46
47
  TrialPlan = {
47
48
  :description => "Plan for integration tests -- with trial",
@@ -25,6 +25,7 @@ END
25
25
  <last-name>Doe</last-name>
26
26
  <number>1234560000001234</number>
27
27
  <cvv>123</cvv>
28
+ <encrypted-card-data>8F34DFB312DC79C24FD5320622F3E11682D79E6B0C0FD881</encrypted-card-data>
28
29
  </customer>
29
30
  END
30
31
 
@@ -34,6 +35,7 @@ END
34
35
  [Braintree] <last-name>Doe</last-name>
35
36
  [Braintree] <number>123456******1234</number>
36
37
  [Braintree] <cvv>***</cvv>
38
+ [Braintree] <encrypted-card-data>***</encrypted-card-data>
37
39
  [Braintree] </customer>
38
40
  END
39
41
  Braintree::Http.new(:config)._format_and_sanitize_body_for_log(input_xml).should == expected_xml
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::LocalPaymentExpired do
4
+ describe "self.new" do
5
+ it "is protected" do
6
+ expect do
7
+ Braintree::LocalPaymentExpired.new
8
+ end.to raise_error(NoMethodError, /protected method .new/)
9
+ end
10
+ end
11
+
12
+ describe "self._new" do
13
+ it "initializes the object with the appropriate attributes set" do
14
+ params = {
15
+ payment_id: "a-payment-id",
16
+ payment_context_id: "a-payment-context-id",
17
+ }
18
+ local_payment_expired = Braintree::LocalPaymentExpired._new(params)
19
+
20
+ local_payment_expired.payment_id.should eq("a-payment-id")
21
+ local_payment_expired.payment_context_id.should eq("a-payment-context-id")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::LocalPaymentFunded do
4
+ describe "self.new" do
5
+ it "is protected" do
6
+ expect do
7
+ Braintree::LocalPaymentFunded.new
8
+ end.to raise_error(NoMethodError, /protected method .new/)
9
+ end
10
+ end
11
+
12
+ describe "self._new" do
13
+ it "initializes the object with the appropriate attributes set" do
14
+ params = {
15
+ payment_id: "a-payment-id",
16
+ payment_context_id: "a-payment-context-id",
17
+ transaction: {
18
+ id: "a-transaction-id",
19
+ amount: "31.00",
20
+ order_id: "an-order-id",
21
+ status: Braintree::Transaction::Status::Settled,
22
+ },
23
+ }
24
+ local_payment_funded = Braintree::LocalPaymentFunded._new(params)
25
+
26
+ local_payment_funded.payment_id.should eq("a-payment-id")
27
+ local_payment_funded.payment_context_id.should eq("a-payment-context-id")
28
+ local_payment_funded.transaction.id.should eq("a-transaction-id")
29
+ local_payment_funded.transaction.amount.should eq(31.0)
30
+ local_payment_funded.transaction.order_id.should eq("an-order-id")
31
+ local_payment_funded.transaction.status.should eq(Braintree::Transaction::Status::Settled)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe Braintree::PaymentMethodNonce do
4
+ let(:payment_method_nonce) {
5
+ Braintree::PaymentMethodNonce._new(
6
+ :gateway,
7
+ :nonce => "some-nonce",
8
+ :type => "CreditCard",
9
+ :default => true,
10
+ :details => {
11
+ :bin => "some-bin"
12
+ },
13
+ :three_d_secure_info => {
14
+ :liability_shift_possible => false,
15
+ :liability_shifted => false
16
+ },
17
+ :bin_data => {
18
+ :country_of_issuance => "USA"
19
+ },
20
+ )
21
+ }
22
+
23
+ describe "#initialize" do
24
+ it "sets attributes" do
25
+ expect(payment_method_nonce.nonce).to eq("some-nonce")
26
+ expect(payment_method_nonce.type).to eq("CreditCard")
27
+ expect(payment_method_nonce.default).to be true
28
+ expect(payment_method_nonce.details.bin).to eq("some-bin")
29
+ expect(payment_method_nonce.three_d_secure_info.liability_shift_possible).to be false
30
+ expect(payment_method_nonce.three_d_secure_info.liability_shifted).to be false
31
+ expect(payment_method_nonce.bin_data.country_of_issuance).to eq("USA")
32
+ end
33
+ end
34
+
35
+ describe "default" do
36
+ it "is aliased to default?" do
37
+ expect(payment_method_nonce.default?).to be true
38
+ end
39
+ end
40
+ end
@@ -25,6 +25,8 @@ describe Braintree::Transaction::PayPalDetails do
25
25
  :refund_from_transaction_fee_currency_iso_code => "123",
26
26
  :refund_id => "refund-id",
27
27
  :seller_protection_status => "seller-protection-status",
28
+ :tax_id => "tax-id",
29
+ :tax_id_type => "tax-id-type",
28
30
  :token => "token",
29
31
  :transaction_fee_amount => "2.00",
30
32
  :transaction_fee_currency_iso_code => "123",
@@ -51,6 +53,8 @@ describe Braintree::Transaction::PayPalDetails do
51
53
  expect(details.refund_from_transaction_fee_currency_iso_code).to eq("123")
52
54
  expect(details.refund_id).to eq("refund-id")
53
55
  expect(details.seller_protection_status).to eq("seller-protection-status")
56
+ expect(details.tax_id).to eq("tax-id")
57
+ expect(details.tax_id_type).to eq("tax-id-type")
54
58
  expect(details.token).to eq("token")
55
59
  expect(details.transaction_fee_amount).to eq("2.00")
56
60
  expect(details.transaction_fee_currency_iso_code).to eq("123")
@@ -21,19 +21,19 @@ describe Braintree::Transaction do
21
21
  it "raises error if passed empty string" do
22
22
  expect do
23
23
  Braintree::Transaction.find("")
24
- end.to raise_error(ArgumentError)
24
+ end.to raise_error(ArgumentError, "id can not be empty")
25
25
  end
26
26
 
27
27
  it "raises error if passed empty string wth space" do
28
28
  expect do
29
29
  Braintree::Transaction.find(" ")
30
- end.to raise_error(ArgumentError)
30
+ end.to raise_error(ArgumentError, "id can not be empty")
31
31
  end
32
32
 
33
33
  it "raises error if passed nil" do
34
34
  expect do
35
35
  Braintree::Transaction.find(nil)
36
- end.to raise_error(ArgumentError)
36
+ end.to raise_error(ArgumentError, "id can not be empty")
37
37
  end
38
38
  end
39
39
 
@@ -317,6 +317,24 @@ describe Braintree::WebhookNotification do
317
317
  end
318
318
  end
319
319
 
320
+ context "transaction review" do
321
+ it " builds a sample notification for a transaction reviewed webhook" do
322
+ sample_notification = Braintree::WebhookTesting.sample_notification(
323
+ Braintree::WebhookNotification::Kind::TransactionReviewed,
324
+ "my_id",
325
+ )
326
+
327
+ notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
328
+
329
+ expect(notification.kind).to eq(Braintree::WebhookNotification::Kind::TransactionReviewed)
330
+ expect(notification.transaction_review.transaction_id).to eq("my_id")
331
+ expect(notification.transaction_review.decision).to eq("decision")
332
+ expect(notification.transaction_review.reviewer_email).to eq("hey@girl.com")
333
+ expect(notification.transaction_review.reviewer_note).to eq("i reviewed this")
334
+ expect(notification.transaction_review.reviewed_time).to_not be_nil
335
+ end
336
+ end
337
+
320
338
  context "us bank account transactions" do
321
339
  it "builds a sample notification for a settlement webhook" do
322
340
  sample_notification = Braintree::WebhookTesting.sample_notification(
@@ -668,6 +686,40 @@ describe Braintree::WebhookNotification do
668
686
  end
669
687
  end
670
688
 
689
+ context "local_payment_expired" do
690
+ it "builds a sample notification for a local_payment_expired webhook" do
691
+ sample_notification = Braintree::WebhookTesting.sample_notification(
692
+ Braintree::WebhookNotification::Kind::LocalPaymentExpired,
693
+ "my_id",
694
+ )
695
+
696
+ notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
697
+ notification.kind.should == Braintree::WebhookNotification::Kind::LocalPaymentExpired
698
+
699
+ local_payment_expired = notification.local_payment_expired
700
+ local_payment_expired.payment_id.should == "PAY-XYZ123"
701
+ local_payment_expired.payment_context_id.should == "cG5b="
702
+ end
703
+ end
704
+
705
+ context "local_payment_funded" do
706
+ it "builds a sample notification for a local_payment_funded webhook" do
707
+ sample_notification = Braintree::WebhookTesting.sample_notification(
708
+ Braintree::WebhookNotification::Kind::LocalPaymentFunded,
709
+ "my_id",
710
+ )
711
+ notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
712
+ notification.kind.should == Braintree::WebhookNotification::Kind::LocalPaymentFunded
713
+
714
+ local_payment_funded = notification.local_payment_funded
715
+ local_payment_funded.payment_id.should == "PAY-XYZ123"
716
+ local_payment_funded.payment_context_id.should == "cG5b="
717
+ local_payment_funded.transaction.id.should == "my_id"
718
+ local_payment_funded.transaction.status.should == Braintree::Transaction::Status::Settled
719
+ local_payment_funded.transaction.amount.should == 49.99
720
+ local_payment_funded.transaction.order_id.should == "order4567"
721
+ end
722
+ end
671
723
 
672
724
  context "local_payment_reversed" do
673
725
  it "builds a sample notification for a local_payment webhook" do
@@ -675,7 +727,6 @@ describe Braintree::WebhookNotification do
675
727
  Braintree::WebhookNotification::Kind::LocalPaymentReversed,
676
728
  "my_id",
677
729
  )
678
-
679
730
  notification = Braintree::WebhookNotification.parse(sample_notification[:bt_signature], sample_notification[:bt_payload])
680
731
  notification.kind.should == Braintree::WebhookNotification::Kind::LocalPaymentReversed
681
732
 
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: 4.1.0
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -104,6 +104,8 @@ files:
104
104
  - lib/braintree/graphql_client.rb
105
105
  - lib/braintree/http.rb
106
106
  - lib/braintree/local_payment_completed.rb
107
+ - lib/braintree/local_payment_expired.rb
108
+ - lib/braintree/local_payment_funded.rb
107
109
  - lib/braintree/local_payment_reversed.rb
108
110
  - lib/braintree/merchant.rb
109
111
  - lib/braintree/merchant_account.rb
@@ -174,6 +176,7 @@ files:
174
176
  - lib/braintree/transaction_gateway.rb
175
177
  - lib/braintree/transaction_line_item.rb
176
178
  - lib/braintree/transaction_line_item_gateway.rb
179
+ - lib/braintree/transaction_review.rb
177
180
  - lib/braintree/transaction_search.rb
178
181
  - lib/braintree/unknown_payment_method.rb
179
182
  - lib/braintree/us_bank_account.rb
@@ -270,10 +273,13 @@ files:
270
273
  - spec/unit/braintree/errors_spec.rb
271
274
  - spec/unit/braintree/http_spec.rb
272
275
  - spec/unit/braintree/local_payment_completed_spec.rb
276
+ - spec/unit/braintree/local_payment_expired_spec.rb
277
+ - spec/unit/braintree/local_payment_funded_spec.rb
273
278
  - spec/unit/braintree/merchant_account_spec.rb
274
279
  - spec/unit/braintree/modification_spec.rb
275
280
  - spec/unit/braintree/payment_method_nonce_details_payer_info_spec.rb
276
281
  - spec/unit/braintree/payment_method_nonce_details_spec.rb
282
+ - spec/unit/braintree/payment_method_nonce_spec.rb
277
283
  - spec/unit/braintree/payment_method_spec.rb
278
284
  - spec/unit/braintree/paypal_account_spec.rb
279
285
  - spec/unit/braintree/resource_collection_spec.rb
@@ -328,7 +334,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
328
334
  - !ruby/object:Gem::Version
329
335
  version: '0'
330
336
  requirements: []
331
- rubygems_version: 3.2.18
337
+ rubygems_version: 3.2.31
332
338
  signing_key:
333
339
  specification_version: 4
334
340
  summary: Braintree Ruby Server SDK