braintree 2.104.0 → 4.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/braintree.gemspec +7 -4
  4. data/lib/braintree/account_updater_daily_report.rb +1 -1
  5. data/lib/braintree/address.rb +2 -23
  6. data/lib/braintree/apple_pay.rb +1 -1
  7. data/lib/braintree/apple_pay_card.rb +11 -1
  8. data/lib/braintree/apple_pay_options.rb +1 -1
  9. data/lib/braintree/authorization_adjustment.rb +1 -1
  10. data/lib/braintree/base_module.rb +6 -0
  11. data/lib/braintree/bin_data.rb +9 -2
  12. data/lib/braintree/client_token.rb +1 -1
  13. data/lib/braintree/configuration.rb +12 -12
  14. data/lib/braintree/connected_merchant_paypal_status_changed.rb +1 -1
  15. data/lib/braintree/connected_merchant_status_transitioned.rb +1 -1
  16. data/lib/braintree/credit_card.rb +2 -77
  17. data/lib/braintree/credit_card_gateway.rb +17 -36
  18. data/lib/braintree/credit_card_verification.rb +18 -5
  19. data/lib/braintree/credit_card_verification_search.rb +1 -1
  20. data/lib/braintree/customer.rb +9 -78
  21. data/lib/braintree/customer_gateway.rb +2 -23
  22. data/lib/braintree/customer_search.rb +1 -1
  23. data/lib/braintree/disbursement.rb +1 -1
  24. data/lib/braintree/{transaction/coinbase_details.rb → dispute/paypal_message.rb} +5 -6
  25. data/lib/braintree/dispute/{history_event.rb → status_history.rb} +3 -1
  26. data/lib/braintree/dispute.rb +32 -8
  27. data/lib/braintree/dispute_gateway.rb +4 -9
  28. data/lib/braintree/dispute_search.rb +6 -3
  29. data/lib/braintree/document_upload.rb +1 -1
  30. data/lib/braintree/enriched_customer_data.rb +21 -0
  31. data/lib/braintree/error_codes.rb +150 -171
  32. data/lib/braintree/exceptions.rb +5 -3
  33. data/lib/braintree/exchange_rate.rb +13 -0
  34. data/lib/braintree/exchange_rate_quote.rb +24 -0
  35. data/lib/braintree/exchange_rate_quote_gateway.rb +35 -0
  36. data/lib/braintree/exchange_rate_quote_input.rb +21 -0
  37. data/lib/braintree/exchange_rate_quote_request.rb +18 -0
  38. data/lib/braintree/exchange_rate_quote_response.rb +18 -0
  39. data/lib/braintree/gateway.rb +4 -14
  40. data/lib/braintree/{android_pay_card.rb → google_pay_card.rb} +11 -3
  41. data/lib/braintree/granted_payment_instrument_update.rb +1 -1
  42. data/lib/braintree/graphql_client.rb +7 -7
  43. data/lib/braintree/http.rb +4 -3
  44. data/lib/braintree/local_payment_completed.rb +2 -2
  45. data/lib/braintree/local_payment_expired.rb +21 -0
  46. data/lib/braintree/local_payment_funded.rb +22 -0
  47. data/lib/braintree/local_payment_reversed.rb +19 -0
  48. data/lib/braintree/merchant.rb +1 -1
  49. data/lib/braintree/merchant_account.rb +1 -1
  50. data/lib/braintree/merchant_account_gateway.rb +3 -1
  51. data/lib/braintree/merchant_gateway.rb +1 -1
  52. data/lib/braintree/modification.rb +1 -1
  53. data/lib/braintree/oauth_credentials.rb +1 -1
  54. data/lib/braintree/oauth_gateway.rb +5 -5
  55. data/lib/braintree/payment_instrument_type.rb +10 -14
  56. data/lib/braintree/payment_method_customer_data_updated_metadata.rb +24 -0
  57. data/lib/braintree/payment_method_gateway.rb +15 -17
  58. data/lib/braintree/payment_method_nonce.rb +7 -4
  59. data/lib/braintree/payment_method_nonce_details.rb +37 -0
  60. data/lib/braintree/payment_method_nonce_details_payer_info.rb +32 -0
  61. data/lib/braintree/payment_method_nonce_gateway.rb +1 -1
  62. data/lib/braintree/payment_method_parser.rb +1 -8
  63. data/lib/braintree/plan.rb +21 -1
  64. data/lib/braintree/plan_gateway.rb +100 -0
  65. data/lib/braintree/processor_response_types.rb +3 -3
  66. data/lib/braintree/resource_collection.rb +8 -3
  67. data/lib/braintree/revoked_payment_method_metadata.rb +1 -1
  68. data/lib/braintree/risk_data/liability_shift.rb +22 -0
  69. data/lib/braintree/risk_data.rb +5 -1
  70. data/lib/braintree/samsung_pay_card.rb +1 -1
  71. data/lib/braintree/settlement_batch_summary.rb +2 -2
  72. data/lib/braintree/subscription.rb +11 -11
  73. data/lib/braintree/successful_result.rb +3 -2
  74. data/lib/braintree/test/credit_card.rb +1 -0
  75. data/lib/braintree/test/nonce.rb +4 -23
  76. data/lib/braintree/three_d_secure_info.rb +22 -12
  77. data/lib/braintree/transaction/disbursement_details.rb +1 -0
  78. data/lib/braintree/transaction/{android_pay_details.rb → google_pay_details.rb} +1 -1
  79. data/lib/braintree/transaction/installment/adjustment.rb +33 -0
  80. data/lib/braintree/transaction/installment.rb +28 -0
  81. data/lib/braintree/transaction/paypal_details.rb +3 -0
  82. data/lib/braintree/transaction/subscription_details.rb +2 -0
  83. data/lib/braintree/transaction.rb +65 -120
  84. data/lib/braintree/transaction_gateway.rb +39 -27
  85. data/lib/braintree/transaction_line_item.rb +1 -1
  86. data/lib/braintree/transaction_review.rb +18 -0
  87. data/lib/braintree/transaction_search.rb +5 -3
  88. data/lib/braintree/unknown_payment_method.rb +1 -1
  89. data/lib/braintree/us_bank_account.rb +3 -3
  90. data/lib/braintree/us_bank_account_verification.rb +1 -1
  91. data/lib/braintree/us_bank_account_verification_gateway.rb +1 -1
  92. data/lib/braintree/util.rb +21 -6
  93. data/lib/braintree/venmo_account.rb +1 -1
  94. data/lib/braintree/venmo_profile_data.rb +23 -0
  95. data/lib/braintree/version.rb +2 -2
  96. data/lib/braintree/visa_checkout_card.rb +2 -2
  97. data/lib/braintree/webhook_notification.rb +44 -30
  98. data/lib/braintree/webhook_notification_gateway.rb +5 -5
  99. data/lib/braintree/webhook_testing_gateway.rb +104 -43
  100. data/lib/braintree/xml/generator.rb +5 -4
  101. data/lib/braintree/xml/parser.rb +22 -35
  102. data/lib/braintree/xml/rexml.rb +4 -5
  103. data/lib/braintree.rb +28 -23
  104. data/spec/integration/braintree/add_on_spec.rb +1 -1
  105. data/spec/integration/braintree/address_spec.rb +30 -113
  106. data/spec/integration/braintree/advanced_search_spec.rb +45 -45
  107. data/spec/integration/braintree/apple_pay_spec.rb +3 -3
  108. data/spec/integration/braintree/braintree_gateway_spec.rb +2 -1
  109. data/spec/integration/braintree/client_api/client_token_spec.rb +14 -14
  110. data/spec/integration/braintree/client_api/spec_helper.rb +5 -31
  111. data/spec/integration/braintree/credit_card_spec.rb +219 -593
  112. data/spec/integration/braintree/credit_card_verification_search_spec.rb +2 -2
  113. data/spec/integration/braintree/credit_card_verification_spec.rb +1 -1
  114. data/spec/integration/braintree/customer_search_spec.rb +8 -8
  115. data/spec/integration/braintree/customer_spec.rb +484 -513
  116. data/spec/integration/braintree/dispute_search_spec.rb +35 -6
  117. data/spec/integration/braintree/dispute_spec.rb +6 -7
  118. data/spec/integration/braintree/error_codes_spec.rb +1 -1
  119. data/spec/integration/braintree/exchange_rate_quote_spec.rb +97 -0
  120. data/spec/integration/braintree/graphql_client_spec.rb +0 -2
  121. data/spec/integration/braintree/http_spec.rb +2 -2
  122. data/spec/integration/braintree/merchant_account_spec.rb +28 -29
  123. data/spec/integration/braintree/merchant_spec.rb +14 -14
  124. data/spec/integration/braintree/oauth_spec.rb +11 -11
  125. data/spec/integration/braintree/payment_method_nonce_spec.rb +29 -35
  126. data/spec/integration/braintree/payment_method_spec.rb +535 -270
  127. data/spec/integration/braintree/payment_method_us_bank_account_spec.rb +17 -13
  128. data/spec/integration/braintree/paypal_account_spec.rb +28 -28
  129. data/spec/integration/braintree/plan_spec.rb +82 -0
  130. data/spec/integration/braintree/samsung_pay_card_spec.rb +9 -9
  131. data/spec/integration/braintree/settlement_batch_summary_spec.rb +8 -8
  132. data/spec/integration/braintree/subscription_spec.rb +144 -149
  133. data/spec/integration/braintree/test/transaction_amounts_spec.rb +2 -2
  134. data/spec/integration/braintree/test_transaction_spec.rb +10 -10
  135. data/spec/integration/braintree/transaction_search_spec.rb +175 -70
  136. data/spec/integration/braintree/transaction_spec.rb +955 -894
  137. data/spec/integration/braintree/transaction_us_bank_account_spec.rb +32 -26
  138. data/spec/integration/braintree/us_bank_account_spec.rb +6 -6
  139. data/spec/integration/braintree/us_bank_account_verification_search_spec.rb +7 -7
  140. data/spec/integration/braintree/us_bank_account_verification_spec.rb +8 -8
  141. data/spec/integration/braintree/visa_checkout_card_spec.rb +5 -5
  142. data/spec/integration/spec_helper.rb +16 -7
  143. data/spec/oauth_test_helper.rb +1 -1
  144. data/spec/script/httpsd.rb +6 -6
  145. data/spec/spec_helper.rb +8 -14
  146. data/spec/unit/braintree/address_spec.rb +1 -9
  147. data/spec/unit/braintree/apple_pay_card_spec.rb +7 -1
  148. data/spec/unit/braintree/client_token_spec.rb +2 -2
  149. data/spec/unit/braintree/configuration_spec.rb +42 -42
  150. data/spec/unit/braintree/credit_card_spec.rb +13 -32
  151. data/spec/unit/braintree/credit_card_verification_search_spec.rb +1 -1
  152. data/spec/unit/braintree/credit_card_verification_spec.rb +8 -4
  153. data/spec/unit/braintree/customer_spec.rb +21 -22
  154. data/spec/unit/braintree/disbursement_spec.rb +7 -7
  155. data/spec/unit/braintree/dispute_search_spec.rb +3 -0
  156. data/spec/unit/braintree/dispute_spec.rb +75 -21
  157. data/spec/unit/braintree/enriched_customer_data_spec.rb +32 -0
  158. data/spec/unit/braintree/error_result_spec.rb +5 -5
  159. data/spec/unit/braintree/errors_spec.rb +8 -8
  160. data/spec/unit/braintree/exchange_rate_quote_input_spec.rb +42 -0
  161. data/spec/unit/braintree/exchange_rate_quote_request_spec.rb +82 -0
  162. data/spec/unit/braintree/exchange_rate_quote_response_spec.rb +52 -0
  163. data/spec/unit/braintree/exchange_rate_quote_spec.rb +42 -0
  164. data/spec/unit/braintree/exchange_rate_spec.rb +23 -0
  165. data/spec/unit/braintree/http_spec.rb +10 -8
  166. data/spec/unit/braintree/local_payment_completed_spec.rb +14 -0
  167. data/spec/unit/braintree/local_payment_expired_spec.rb +24 -0
  168. data/spec/unit/braintree/local_payment_funded_spec.rb +34 -0
  169. data/spec/unit/braintree/merchant_account_spec.rb +1 -1
  170. data/spec/unit/braintree/payment_method_customer_data_updated_metadata_spec.rb +45 -0
  171. data/spec/unit/braintree/payment_method_nonce_details_payer_info_spec.rb +31 -0
  172. data/spec/unit/braintree/payment_method_nonce_details_spec.rb +43 -0
  173. data/spec/unit/braintree/payment_method_nonce_spec.rb +40 -0
  174. data/spec/unit/braintree/payment_method_spec.rb +1 -1
  175. data/spec/unit/braintree/paypal_account_spec.rb +2 -2
  176. data/spec/unit/braintree/resource_collection_spec.rb +30 -1
  177. data/spec/unit/braintree/risk_data/liability_shift.rb +26 -0
  178. data/spec/unit/braintree/risk_data_spec.rb +38 -8
  179. data/spec/unit/braintree/subscription_search_spec.rb +1 -1
  180. data/spec/unit/braintree/successful_result_spec.rb +1 -1
  181. data/spec/unit/braintree/three_d_secure_info_spec.rb +32 -14
  182. data/spec/unit/braintree/transaction/credit_card_details_spec.rb +3 -3
  183. data/spec/unit/braintree/transaction/customer_details_spec.rb +1 -1
  184. data/spec/unit/braintree/transaction/deposit_details_spec.rb +2 -2
  185. data/spec/unit/braintree/transaction/installment_spec.rb +25 -0
  186. data/spec/unit/braintree/transaction/paypal_details_spec.rb +7 -1
  187. data/spec/unit/braintree/transaction_search_spec.rb +12 -12
  188. data/spec/unit/braintree/transaction_spec.rb +36 -54
  189. data/spec/unit/braintree/util_spec.rb +55 -21
  190. data/spec/unit/braintree/validation_error_collection_spec.rb +36 -36
  191. data/spec/unit/braintree/venmo_profile_data_spec.rb +32 -0
  192. data/spec/unit/braintree/webhook_notification_spec.rb +166 -57
  193. data/spec/unit/braintree/xml/parser_spec.rb +21 -16
  194. data/spec/unit/braintree/xml_spec.rb +31 -31
  195. metadata +62 -30
  196. data/lib/braintree/amex_express_checkout_card.rb +0 -40
  197. data/lib/braintree/coinbase_account.rb +0 -34
  198. data/lib/braintree/europe_bank_account.rb +0 -36
  199. data/lib/braintree/europe_bank_account_gateway.rb +0 -17
  200. data/lib/braintree/ideal_payment.rb +0 -61
  201. data/lib/braintree/ideal_payment_gateway.rb +0 -19
  202. data/lib/braintree/masterpass_card.rb +0 -83
  203. data/lib/braintree/settlement_batch.rb +0 -0
  204. data/lib/braintree/transaction/amex_express_checkout_details.rb +0 -21
  205. data/lib/braintree/transaction/ideal_payment_details.rb +0 -19
  206. data/lib/braintree/transaction/masterpass_card_details.rb +0 -49
  207. data/lib/braintree/transparent_redirect.rb +0 -40
  208. data/lib/braintree/transparent_redirect_gateway.rb +0 -105
  209. data/spec/hacks/tcp_socket.rb +0 -18
  210. data/spec/integration/braintree/coinbase_spec.rb +0 -34
  211. data/spec/integration/braintree/masterpass_card_spec.rb +0 -97
  212. data/spec/integration/braintree/transparent_redirect_spec.rb +0 -268
  213. data/spec/unit/braintree/transparent_redirect_spec.rb +0 -223
@@ -39,7 +39,7 @@ module Braintree
39
39
  end
40
40
 
41
41
  def _most_recent_verification(attributes)
42
- verification = (attributes[:verifications] || []).sort_by{ |verification| verification[:created_at] }.reverse.first
42
+ verification = (attributes[:verifications] || []).sort_by { |verification| verification[:created_at] }.reverse.first
43
43
  CreditCardVerification._new(verification) if verification
44
44
  end
45
45
 
@@ -84,7 +84,7 @@ module Braintree
84
84
  end
85
85
 
86
86
  def self._new(*args) # :nodoc:
87
- self.new *args
87
+ self.new(*args)
88
88
  end
89
89
  end
90
90
  end
@@ -1,12 +1,17 @@
1
- require 'ostruct'
1
+ require "ostruct"
2
2
 
3
3
  module Braintree
4
4
  class WebhookNotification
5
5
  include BaseModule
6
6
 
7
7
  module Kind
8
+
9
+ AccountUpdaterDailyReport = "account_updater_daily_report"
10
+
8
11
  Check = "check"
9
12
 
13
+ ConnectedMerchantPayPalStatusChanged = "connected_merchant_paypal_status_changed"
14
+ ConnectedMerchantStatusTransitioned = "connected_merchant_status_transitioned"
10
15
  Disbursement = "disbursement"
11
16
  DisbursementException = "disbursement_exception"
12
17
 
@@ -17,6 +22,28 @@ module Braintree
17
22
  DisputeDisputed = "dispute_disputed"
18
23
  DisputeExpired = "dispute_expired"
19
24
 
25
+ GrantedPaymentInstrumentRevoked = "granted_payment_instrument_revoked"
26
+
27
+ GrantorUpdatedGrantedPaymentMethod = "grantor_updated_granted_payment_method"
28
+ GrantedPaymentMethodRevoked = "granted_payment_method_revoked"
29
+
30
+ LocalPaymentCompleted = "local_payment_completed"
31
+ LocalPaymentExpired = "local_payment_expired"
32
+ LocalPaymentFunded = "local_payment_funded"
33
+ LocalPaymentReversed = "local_payment_reversed"
34
+
35
+ OAuthAccessRevoked = "oauth_access_revoked"
36
+
37
+ PartnerMerchantConnected = "partner_merchant_connected"
38
+ PartnerMerchantDisconnected = "partner_merchant_disconnected"
39
+ PartnerMerchantDeclined = "partner_merchant_declined"
40
+
41
+ PaymentMethodCustomerDataUpdated = "payment_method_customer_data_updated"
42
+
43
+ PaymentMethodRevokedByCustomer = "payment_method_revoked_by_customer"
44
+
45
+ RecipientUpdatedGrantedPaymentMethod = "recipient_updated_granted_payment_method"
46
+
20
47
  SubscriptionCanceled = "subscription_canceled"
21
48
  SubscriptionChargedSuccessfully = "subscription_charged_successfully"
22
49
  SubscriptionChargedUnsuccessfully = "subscription_charged_unsuccessfully"
@@ -27,33 +54,11 @@ module Braintree
27
54
 
28
55
  SubMerchantAccountApproved = "sub_merchant_account_approved"
29
56
  SubMerchantAccountDeclined = "sub_merchant_account_declined"
57
+
30
58
  TransactionDisbursed = "transaction_disbursed"
59
+ TransactionReviewed = "transaction_reviewed"
31
60
  TransactionSettlementDeclined = "transaction_settlement_declined"
32
61
  TransactionSettled = "transaction_settled"
33
- PartnerMerchantConnected = "partner_merchant_connected"
34
- PartnerMerchantDisconnected = "partner_merchant_disconnected"
35
- PartnerMerchantDeclined = "partner_merchant_declined"
36
-
37
- AccountUpdaterDailyReport = "account_updater_daily_report"
38
-
39
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
40
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
41
- IdealPaymentComplete = "ideal_payment_complete"
42
- IdealPaymentFailed = "ideal_payment_failed"
43
-
44
- OAuthAccessRevoked = "oauth_access_revoked"
45
- ConnectedMerchantStatusTransitioned = "connected_merchant_status_transitioned"
46
- ConnectedMerchantPayPalStatusChanged = "connected_merchant_paypal_status_changed"
47
-
48
- # NEXT_MAJOR_VERSION remove GrantedPaymentInstrumentUpdate. Kind is not sent by Braintree Gateway.
49
- # Kind will either be GrantorUpdatedGrantedPaymentMethod or RecipientUpdatedGrantedPaymentMethod.
50
- GrantedPaymentInstrumentUpdate = "granted_payment_instrument_update"
51
- GrantorUpdatedGrantedPaymentMethod = "grantor_updated_granted_payment_method"
52
- RecipientUpdatedGrantedPaymentMethod = "recipient_updated_granted_payment_method"
53
- GrantedPaymentInstrumentRevoked = "granted_payment_instrument_revoked"
54
- PaymentMethodRevokedByCustomer = "payment_method_revoked_by_customer"
55
-
56
- LocalPaymentCompleted = "local_payment_completed"
57
62
  end
58
63
 
59
64
  attr_reader :account_updater_daily_report
@@ -63,15 +68,19 @@ module Braintree
63
68
  attr_reader :dispute
64
69
  attr_reader :granted_payment_instrument_update
65
70
  attr_reader :revoked_payment_method_metadata
66
- attr_reader :ideal_payment
67
71
  attr_reader :kind
68
72
  attr_reader :local_payment_completed
73
+ attr_reader :local_payment_expired
74
+ attr_reader :local_payment_funded
75
+ attr_reader :local_payment_reversed
69
76
  attr_reader :oauth_access_revocation
70
77
  attr_reader :partner_merchant
78
+ attr_reader :payment_method_customer_data_updated_metadata
71
79
  attr_reader :source_merchant_id
72
80
  attr_reader :subscription
73
81
  attr_reader :timestamp
74
82
  attr_reader :transaction
83
+ attr_reader :transaction_review
75
84
 
76
85
  def self.parse(*args)
77
86
  Configuration.gateway.webhook_notification.parse(*args)
@@ -90,15 +99,20 @@ module Braintree
90
99
  @oauth_access_revocation = OpenStruct.new(@subject[:oauth_application_revocation]) if @subject.has_key?(:oauth_application_revocation)
91
100
  @subscription = Subscription._new(gateway, @subject[:subscription]) if @subject.has_key?(:subscription)
92
101
  @transaction = Transaction._new(gateway, @subject[:transaction]) if @subject.has_key?(:transaction)
102
+ @transaction_review = OpenStruct.new(@subject[:transaction_review]) if @subject.has_key?(:transaction_review)
93
103
  @disbursement = Disbursement._new(gateway, @subject[:disbursement]) if @subject.has_key?(:disbursement)
94
104
  @dispute = Dispute._new(@subject[:dispute]) if @subject.has_key?(:dispute)
95
105
  @account_updater_daily_report = AccountUpdaterDailyReport._new(@subject[:account_updater_daily_report]) if @subject.has_key?(:account_updater_daily_report)
96
- @ideal_payment = Braintree::IdealPayment._new(gateway, @subject[:ideal_payment]) if @subject.has_key?(:ideal_payment)
97
106
  @connected_merchant_status_transitioned = ConnectedMerchantStatusTransitioned._new(@subject[:connected_merchant_status_transitioned]) if @subject.has_key?(:connected_merchant_status_transitioned)
98
107
  @connected_merchant_paypal_status_changed = ConnectedMerchantPayPalStatusChanged._new(@subject[:connected_merchant_paypal_status_changed]) if @subject.has_key?(:connected_merchant_paypal_status_changed)
99
108
  @granted_payment_instrument_update = GrantedPaymentInstrumentUpdate._new(@subject[:granted_payment_instrument_update]) if @subject.has_key?(:granted_payment_instrument_update)
100
- @revoked_payment_method_metadata = RevokedPaymentMethodMetadata._new(gateway, @subject) if [Kind::GrantedPaymentInstrumentRevoked, Kind::PaymentMethodRevokedByCustomer].include?(@kind)
101
- @local_payment_completed = LocalPaymentCompleted._new(@subject[:local_payment]) if @subject.has_key?(:local_payment)
109
+ @revoked_payment_method_metadata = RevokedPaymentMethodMetadata._new(gateway, @subject) if [Kind::GrantedPaymentInstrumentRevoked, Kind::PaymentMethodRevokedByCustomer, Kind::GrantedPaymentMethodRevoked].include?(@kind)
110
+ @local_payment_completed = LocalPaymentCompleted._new(@subject[:local_payment]) if @subject.has_key?(:local_payment) && Kind::LocalPaymentCompleted == @kind
111
+ @local_payment_expired = LocalPaymentExpired._new(@subject[:local_payment_expired]) if @subject.has_key?(:local_payment_expired) && Kind::LocalPaymentExpired == @kind
112
+ @local_payment_funded = LocalPaymentFunded._new(@subject[:local_payment_funded]) if @subject.has_key?(:local_payment_funded) && Kind::LocalPaymentFunded == @kind
113
+ @local_payment_reversed = LocalPaymentReversed._new(@subject[:local_payment_reversed]) if @subject.has_key?(:local_payment_reversed) && Kind::LocalPaymentReversed == @kind
114
+ @payment_method_customer_data_updated_metadata = PaymentMethodCustomerDataUpdatedMetadata._new(gateway, @subject[:payment_method_customer_data_updated_metadata]) if @subject.has_key?(:payment_method_customer_data_updated_metadata) && Kind::PaymentMethodCustomerDataUpdated == @kind
115
+
102
116
  end
103
117
 
104
118
  def merchant_account
@@ -120,7 +134,7 @@ module Braintree
120
134
  class << self
121
135
  protected :new
122
136
  def _new(*args) # :nodoc:
123
- self.new *args
137
+ self.new(*args)
124
138
  end
125
139
  end
126
140
  end
@@ -7,8 +7,8 @@ module Braintree
7
7
  end
8
8
 
9
9
  def parse(signature_string, payload)
10
- raise InvalidSignature, 'signature cannot be nil' if signature_string.nil?
11
- raise InvalidSignature, 'payload cannot be nil' if payload.nil?
10
+ raise InvalidSignature, "signature cannot be nil" if signature_string.nil?
11
+ raise InvalidSignature, "payload cannot be nil" if payload.nil?
12
12
  if payload =~ /[^A-Za-z0-9+=\/\n]/
13
13
  raise InvalidSignature, "payload contains illegal characters"
14
14
  end
@@ -18,7 +18,7 @@ module Braintree
18
18
  end
19
19
 
20
20
  def verify(challenge)
21
- raise InvalidChallenge, 'challenge contains non-hex characters' unless challenge =~ /\A[a-f0-9]{20,32}\z/
21
+ raise InvalidChallenge, "challenge contains non-hex characters" unless challenge =~ /\A[a-f0-9]{20,32}\z/
22
22
  digest = Braintree::Digest.hexdigest(@config.private_key, challenge)
23
23
  "#{@config.public_key}|#{digest}"
24
24
  end
@@ -34,13 +34,13 @@ module Braintree
34
34
 
35
35
  def _verify_signature(signature_string, payload)
36
36
  public_key, signature = _matching_signature_pair(signature_string)
37
- raise InvalidSignature, 'no matching public key' if public_key.nil?
37
+ raise InvalidSignature, "no matching public key" if public_key.nil?
38
38
 
39
39
  signature_matches = [payload, payload + "\n"].any? do |payload|
40
40
  payload_signature = Braintree::Digest.hexdigest(@config.private_key, payload)
41
41
  Braintree::Digest.secure_compare(signature, payload_signature)
42
42
  end
43
- raise InvalidSignature, 'signature does not match payload - one has been modified' unless signature_matches
43
+ raise InvalidSignature, "signature does not match payload - one has been modified" unless signature_matches
44
44
  end
45
45
  end
46
46
  end
@@ -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
@@ -78,25 +80,24 @@ module Braintree
78
80
  _auth_status_transitioned_sample_xml(id)
79
81
  when Braintree::WebhookNotification::Kind::ConnectedMerchantPayPalStatusChanged
80
82
  _auth_paypal_status_changed_sample_xml(id)
81
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
82
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
83
- when Braintree::WebhookNotification::Kind::IdealPaymentComplete
84
- _ideal_payment_complete_sample_xml(id)
85
- # NEXT_MAJOR_VERSION Remove this class as legacy Ideal has been removed/disabled in the Braintree Gateway
86
- # DEPRECATED If you're looking to accept iDEAL as a payment method contact accounts@braintreepayments.com for a solution.
87
- when Braintree::WebhookNotification::Kind::IdealPaymentFailed
88
- _ideal_payment_failed_sample_xml(id)
89
- # NEXT_MAJOR_VERSION remove GrantedPaymentInstrumentUpdate
90
- when Braintree::WebhookNotification::Kind::GrantedPaymentInstrumentUpdate
91
- _granted_payment_instrument_update_sample_xml(id)
92
83
  when Braintree::WebhookNotification::Kind::GrantorUpdatedGrantedPaymentMethod
93
84
  _granted_payment_instrument_update_sample_xml(id)
94
85
  when Braintree::WebhookNotification::Kind::RecipientUpdatedGrantedPaymentMethod
95
86
  _granted_payment_instrument_update_sample_xml(id)
87
+ when Braintree::WebhookNotification::Kind::GrantedPaymentMethodRevoked
88
+ _granted_payment_method_revoked_xml(id)
96
89
  when Braintree::WebhookNotification::Kind::PaymentMethodRevokedByCustomer
97
90
  _payment_method_revoked_by_customer_sample_xml(id)
98
91
  when Braintree::WebhookNotification::Kind::LocalPaymentCompleted
99
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)
97
+ when Braintree::WebhookNotification::Kind::LocalPaymentReversed
98
+ _local_payment_reversed_sample_xml
99
+ when Braintree::WebhookNotification::Kind::PaymentMethodCustomerDataUpdated
100
+ _payment_method_customer_data_updated_sample_xml(id)
100
101
  else
101
102
  _subscription_sample_xml(id)
102
103
  end
@@ -251,6 +252,19 @@ module Braintree
251
252
  XML
252
253
  end
253
254
 
255
+ def _transaction_reviewed_sample_xml(id)
256
+
257
+ <<-XML
258
+ <transaction-review>
259
+ <transaction-id>my_id</transaction-id>
260
+ <decision>decision</decision>
261
+ <reviewer-email>hey@girl.com</reviewer-email>
262
+ <reviewer-note>i reviewed this</reviewer-note>
263
+ <reviewed-time type="datetime">2017-06-16T20:44:41Z</reviewed-time>
264
+ </transaction-review>
265
+ XML
266
+ end
267
+
254
268
  def _transaction_settled_sample_xml(id)
255
269
  <<-XML
256
270
  <transaction>
@@ -867,38 +881,6 @@ module Braintree
867
881
  XML
868
882
  end
869
883
 
870
- def _ideal_payment_complete_sample_xml(id)
871
- <<-XML
872
- <ideal-payment>
873
- <id>#{id}</id>
874
- <status>COMPLETE</status>
875
- <issuer>ABCISSUER</issuer>
876
- <order-id>ORDERABC</order-id>
877
- <currency>EUR</currency>
878
- <amount>10.00</amount>
879
- <created-at>2016-11-29T23:27:34.547Z</created-at>
880
- <approval-url>https://example.com</approval-url>
881
- <ideal-transaction-id>1234567890</ideal-transaction-id>
882
- </ideal-payment>
883
- XML
884
- end
885
-
886
- def _ideal_payment_failed_sample_xml(id)
887
- <<-XML
888
- <ideal-payment>
889
- <id>#{id}</id>
890
- <status>FAILED</status>
891
- <issuer>ABCISSUER</issuer>
892
- <order-id>ORDERABC</order-id>
893
- <currency>EUR</currency>
894
- <amount>10.00</amount>
895
- <created-at>2016-11-29T23:27:34.547Z</created-at>
896
- <approval-url>https://example.com</approval-url>
897
- <ideal-transaction-id>1234567890</ideal-transaction-id>
898
- </ideal-payment>
899
- XML
900
- end
901
-
902
884
  def _granted_payment_instrument_update_sample_xml(id)
903
885
  <<-XML
904
886
  <granted-payment-instrument-update>
@@ -918,6 +900,10 @@ module Braintree
918
900
  XML
919
901
  end
920
902
 
903
+ def _granted_payment_method_revoked_xml(id)
904
+ _venmo_account_xml(id)
905
+ end
906
+
921
907
  def _payment_method_revoked_by_customer_sample_xml(id)
922
908
  <<-XML
923
909
  <paypal-account>
@@ -955,5 +941,80 @@ module Braintree
955
941
  </local-payment>
956
942
  XML
957
943
  end
944
+
945
+ def _local_payment_expired_sample_xml
946
+ <<-XML
947
+ <local-payment-expired>
948
+ <payment-id>PAY-XYZ123</payment-id>
949
+ <payment-context-id>cG5b=</payment-context-id>
950
+ </local-payment-expired>
951
+ XML
952
+ end
953
+
954
+ def _local_payment_funded_sample_xml(id)
955
+ <<-XML
956
+ <local-payment-funded>
957
+ <payment-id>PAY-XYZ123</payment-id>
958
+ <payment-context-id>cG5b=</payment-context-id>
959
+ <transaction>
960
+ <id>#{id}</id>
961
+ <status>settled</status>
962
+ <amount>49.99</amount>
963
+ <order-id>order4567</order-id>
964
+ </transaction>
965
+ </local-payment-funded>
966
+ XML
967
+ end
968
+
969
+ def _local_payment_reversed_sample_xml
970
+ <<-XML
971
+ <local-payment-reversed>
972
+ <payment-id>PAY-XYZ123</payment-id>
973
+ <payment-context-id>cG5b=</payment-context-id>
974
+ </local-payment-reversed>
975
+ XML
976
+ end
977
+
978
+ def _payment_method_customer_data_updated_sample_xml(id)
979
+ <<-XML
980
+ <payment-method-customer-data-updated-metadata>
981
+ <token>TOKEN-12345</token>
982
+ <payment-method>
983
+ #{_venmo_account_xml(id)}
984
+ </payment-method>
985
+ <datetime-updated type='dateTime'>2022-01-01T21:28:37Z</datetime-updated>
986
+ <enriched-customer-data>
987
+ <fields-updated type='array'>
988
+ <item>username</item>
989
+ </fields-updated>
990
+ <profile-data>
991
+ <username>venmo_username</username>
992
+ <first-name>John</first-name>
993
+ <last-name>Doe</last-name>
994
+ <phone-number>1231231234</phone-number>
995
+ <email>john.doe@paypal.com</email>
996
+ </profile-data>
997
+ </enriched-customer-data>
998
+ </payment-method-customer-data-updated-metadata>
999
+ XML
1000
+ end
1001
+
1002
+ def _venmo_account_xml(id)
1003
+ <<-XML
1004
+ <venmo-account>
1005
+ <created-at type='dateTime'>2018-10-11T21:28:37Z</created-at>
1006
+ <updated-at type='dateTime'>2018-10-11T21:28:37Z</updated-at>
1007
+ <default type='boolean'>true</default>
1008
+ <image-url>https://assets.braintreegateway.com/payment_method_logo/venmo.png?environment=test</image-url>
1009
+ <token>#{id}</token>
1010
+ <source-description>Venmo Account: venmojoe</source-description>
1011
+ <username>venmojoe</username>
1012
+ <venmo-user-id>456</venmo-user-id>
1013
+ <subscriptions type='array'/>
1014
+ <customer-id>venmo_customer_id</customer-id>
1015
+ <global-id>cGF5bWVudG1ldGhvZF92ZW5tb2FjY291bnQ</global-id>
1016
+ </venmo-account>
1017
+ XML
1018
+ end
958
1019
  end
959
1020
  end
@@ -12,6 +12,7 @@ module Braintree
12
12
  "Date" => "datetime",
13
13
  "DateTime" => "datetime",
14
14
  "Time" => "datetime",
15
+ "ActiveSupport::TimeWithZone" => "datetime"
15
16
  }
16
17
 
17
18
  XML_FORMATTING_NAMES = {
@@ -25,7 +26,7 @@ module Braintree
25
26
  date_or_time.respond_to?(:xmlschema) ? date_or_time.xmlschema : date_or_time.to_s
26
27
  end,
27
28
  "bigdecimal" => Proc.new do |bigdecimal|
28
- str = bigdecimal.to_s('F')
29
+ str = bigdecimal.to_s("F")
29
30
  if str =~ /\.\d$/
30
31
  str += "0"
31
32
  end
@@ -61,15 +62,15 @@ module Braintree
61
62
  else
62
63
  type_name = XML_TYPE_NAMES[value.class.name]
63
64
 
64
- attributes = ((value.nil? || type_name.nil?) ? {} : { :type => type_name })
65
+ attributes = ((value.nil? || type_name.nil?) ? {} : {:type => type_name})
65
66
  if value.nil?
66
67
  attributes[:nil] = true
67
68
  end
68
69
 
69
- formatting_name = XML_FORMATTING_NAMES[value.class.name]
70
+ formatting_name = XML_FORMATTING_NAMES[value.class.name]
70
71
  options[:builder].tag!(_xml_escape(key),
71
72
  XML_FORMATTING[formatting_name] ? XML_FORMATTING[formatting_name].call(value) : value,
72
- attributes
73
+ attributes,
73
74
  )
74
75
  end
75
76
  end
@@ -2,7 +2,7 @@
2
2
  # under the MIT license, copyright (c) 2005-2009 David Heinemeier Hansson
3
3
  module Braintree
4
4
  module Xml # :nodoc:
5
- CONTENT_ROOT = '__content__'
5
+ CONTENT_ROOT = "__content__"
6
6
 
7
7
  module Parser # :nodoc:
8
8
  XML_PARSING = {
@@ -13,88 +13,75 @@ module Braintree
13
13
 
14
14
  def self.hash_from_xml(xml, parser = _determine_parser)
15
15
  standardized_hash_structure = parser.parse(xml)
16
- with_underscores_in_keys = _unrename_keys(standardized_hash_structure)
17
- typecasted_xml = _typecast_xml_value(with_underscores_in_keys)
18
- Util.symbolize_keys(typecasted_xml)
16
+ transformed_xml = _transform_xml(standardized_hash_structure)
17
+ Util.symbolize_keys(transformed_xml)
19
18
  end
20
19
 
21
20
  def self._determine_parser
22
- # LibXML causes a segfault in Ruby 2.0.0. We need to fall back to Rexml to prevent this segfault.
23
- if !RUBY_VERSION.start_with?("2.0") && defined?(::LibXML::XML) && ::LibXML::XML.respond_to?(:default_keep_blanks=)
21
+ # If LibXML is not available, we fall back to REXML
22
+ # This allows us to be compatible with JRuby, which LibXML does not support
23
+ if defined?(::LibXML::XML) && ::LibXML::XML.respond_to?(:default_keep_blanks=)
24
24
  ::Braintree::Xml::Libxml
25
25
  else
26
26
  ::Braintree::Xml::Rexml
27
27
  end
28
28
  end
29
29
 
30
- def self._typecast_xml_value(value)
30
+ # Transform into standard Ruby types and convert all keys to snake_case instead of dash-case
31
+ def self._transform_xml(value)
31
32
  case value.class.to_s
32
- when 'Hash'
33
- if value['type'] == 'array'
34
- child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
33
+ when "Hash"
34
+ if value["type"] == "array"
35
+ child_key, entries = value.detect { |k,v| k != "type" } # child_key is throwaway
35
36
  if entries.nil? || ((c = value[CONTENT_ROOT]) && c.strip.empty?)
36
37
  []
37
38
  else
38
39
  case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
39
40
  when "Array"
40
- entries.collect { |v| _typecast_xml_value(v) }
41
+ entries.collect { |v| _transform_xml(v) }
41
42
  when "Hash"
42
- [_typecast_xml_value(entries)]
43
+ [_transform_xml(entries)]
43
44
  else
44
45
  raise "can't typecast #{entries.inspect}"
45
46
  end
46
47
  end
47
48
  elsif value.has_key?(CONTENT_ROOT)
48
49
  content = value[CONTENT_ROOT]
49
- if parser = XML_PARSING[value["type"]]
50
+ if (parser = XML_PARSING[value["type"]])
50
51
  XML_PARSING[value["type"]].call(content)
51
52
  else
52
53
  content
53
54
  end
54
- elsif value['type'] == 'string' && value['nil'] != 'true'
55
+ elsif value["type"] == "string" && value["nil"] != "true"
55
56
  ""
56
57
  elsif value == {}
57
58
  ""
58
- elsif value.nil? || value['nil'] == 'true'
59
+ elsif value.nil? || value["nil"] == "true"
59
60
  nil
60
61
  # If the type is the only element which makes it then
61
62
  # this still makes the value nil, except if type is
62
63
  # a XML node(where type['value'] is a Hash)
63
- elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
64
+ elsif value["type"] && value.size == 1 && !value["type"].is_a?(::Hash)
64
65
  raise "is this needed?"
65
66
  nil
66
67
  else
67
68
  xml_value = value.inject({}) do |h,(k,v)|
68
- h[k] = _typecast_xml_value(v)
69
+ h[k.to_s.tr("-", "_")] = _transform_xml(v) # convert dashes to underscores in keys
69
70
  h
70
71
  end
71
72
  xml_value
72
73
  end
73
- when 'Array'
74
- value.map! { |i| _typecast_xml_value(i) }
74
+ when "Array"
75
+ value.map! { |i| _transform_xml(i) }
75
76
  case value.length
76
77
  when 0 then nil
77
78
  when 1 then value.first
78
79
  else value
79
80
  end
80
- when 'String'
81
+ when "String"
81
82
  value
82
83
  else
83
- raise "can't typecast #{value.class.name} - #{value.inspect}"
84
- end
85
- end
86
-
87
- def self._unrename_keys(params)
88
- case params.class.to_s
89
- when "Hash"
90
- params.inject({}) do |h,(k,v)|
91
- h[k.to_s.tr("-", "_")] = _unrename_keys(v)
92
- h
93
- end
94
- when "Array"
95
- params.map { |v| _unrename_keys(v) }
96
- else
97
- params
84
+ raise "can't transform #{value.class.name} - #{value.inspect}"
98
85
  end
99
86
  end
100
87
  end
@@ -4,10 +4,10 @@ module Braintree
4
4
  module Xml # :nodoc:
5
5
  module Rexml # :nodoc:
6
6
 
7
- CONTENT_KEY = '__content__'.freeze
7
+ CONTENT_KEY = "__content__".freeze
8
8
 
9
9
  def self.parse(string)
10
- require 'rexml/document' unless defined?(REXML::Document)
10
+ require "rexml/document" unless defined?(REXML::Document)
11
11
  doc = REXML::Document.new(string)
12
12
  _merge_element!({}, doc.root)
13
13
  end
@@ -20,7 +20,7 @@ module Braintree
20
20
  hash = _get_attributes(element)
21
21
 
22
22
  if element.has_elements?
23
- element.each_element {|child| _merge_element!(hash, child) }
23
+ element.each_element { |child| _merge_element!(hash, child) }
24
24
  _merge_texts!(hash, element) unless _empty_content?(element)
25
25
  hash
26
26
  else
@@ -36,7 +36,7 @@ module Braintree
36
36
  _merge!(
37
37
  hash,
38
38
  CONTENT_KEY,
39
- element.texts.map { |t| t.value}.join
39
+ element.texts.map { |t| t.value }.join,
40
40
  )
41
41
  end
42
42
  end
@@ -68,4 +68,3 @@ module Braintree
68
68
  end
69
69
  end
70
70
  end
71
-