adyen-ruby-api-library 6.0.0 → 10.1.2

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/release.yml +18 -0
  4. data/.github/workflows/codeql.yml +37 -0
  5. data/.github/workflows/label_new_issues.yml +15 -0
  6. data/.github/workflows/release.yml +40 -0
  7. data/.github/workflows/ruby.yml +2 -2
  8. data/.github/workflows/rubygems_release.yml +18 -0
  9. data/.github/workflows/stale.yml +26 -0
  10. data/.gitignore +3 -0
  11. data/.rubocop.yml +8 -0
  12. data/CONTRIBUTING.md +1 -1
  13. data/Gemfile +7 -7
  14. data/Makefile +79 -0
  15. data/README.md +158 -20
  16. data/Rakefile +3 -3
  17. data/VERSION +2 -0
  18. data/adyen-ruby-api-library.gemspec +6 -3
  19. data/bin/console +2 -2
  20. data/lib/adyen/client.rb +213 -99
  21. data/lib/adyen/errors.rb +30 -22
  22. data/lib/adyen/hash_with_accessors.rb +12 -7
  23. data/lib/adyen/services/balanceControlService.rb +27 -0
  24. data/lib/adyen/services/balancePlatform/account_holders_api.rb +76 -0
  25. data/lib/adyen/services/balancePlatform/balance_accounts_api.rb +116 -0
  26. data/lib/adyen/services/balancePlatform/bank_account_validation_api.rb +26 -0
  27. data/lib/adyen/services/balancePlatform/card_orders_api.rb +36 -0
  28. data/lib/adyen/services/balancePlatform/grant_accounts_api.rb +26 -0
  29. data/lib/adyen/services/balancePlatform/grant_offers_api.rb +36 -0
  30. data/lib/adyen/services/balancePlatform/manage_card_pin_api.rb +46 -0
  31. data/lib/adyen/services/balancePlatform/manage_sca_devices_api.rb +56 -0
  32. data/lib/adyen/services/balancePlatform/network_tokens_api.rb +36 -0
  33. data/lib/adyen/services/balancePlatform/payment_instrument_groups_api.rb +46 -0
  34. data/lib/adyen/services/balancePlatform/payment_instruments_api.rb +86 -0
  35. data/lib/adyen/services/balancePlatform/platform_api.rb +46 -0
  36. data/lib/adyen/services/balancePlatform/transaction_rules_api.rb +56 -0
  37. data/lib/adyen/services/balancePlatform/transfer_routes_api.rb +26 -0
  38. data/lib/adyen/services/balancePlatform.rb +89 -0
  39. data/lib/adyen/services/binLookup.rb +37 -0
  40. data/lib/adyen/services/checkout/donations_api.rb +36 -0
  41. data/lib/adyen/services/checkout/modifications_api.rb +76 -0
  42. data/lib/adyen/services/checkout/orders_api.rb +46 -0
  43. data/lib/adyen/services/checkout/payment_links_api.rb +46 -0
  44. data/lib/adyen/services/checkout/payments_api.rb +76 -0
  45. data/lib/adyen/services/checkout/recurring_api.rb +46 -0
  46. data/lib/adyen/services/checkout/utility_api.rb +48 -0
  47. data/lib/adyen/services/checkout.rb +29 -108
  48. data/lib/adyen/services/dataProtection.rb +27 -0
  49. data/lib/adyen/services/disputes.rb +67 -0
  50. data/lib/adyen/services/legalEntityManagement/business_lines_api.rb +56 -0
  51. data/lib/adyen/services/legalEntityManagement/documents_api.rb +56 -0
  52. data/lib/adyen/services/legalEntityManagement/hosted_onboarding_api.rb +46 -0
  53. data/lib/adyen/services/legalEntityManagement/legal_entities_api.rb +76 -0
  54. data/lib/adyen/services/legalEntityManagement/pci_questionnaires_api.rb +66 -0
  55. data/lib/adyen/services/legalEntityManagement/tax_e_delivery_consent_api.rb +36 -0
  56. data/lib/adyen/services/legalEntityManagement/terms_of_service_api.rb +66 -0
  57. data/lib/adyen/services/legalEntityManagement/transfer_instruments_api.rb +56 -0
  58. data/lib/adyen/services/legalEntityManagement.rb +59 -0
  59. data/lib/adyen/services/management/account_company_level_api.rb +46 -0
  60. data/lib/adyen/services/management/account_merchant_level_api.rb +56 -0
  61. data/lib/adyen/services/management/account_store_level_api.rb +96 -0
  62. data/lib/adyen/services/management/allowed_origins_company_level_api.rb +56 -0
  63. data/lib/adyen/services/management/allowed_origins_merchant_level_api.rb +56 -0
  64. data/lib/adyen/services/management/android_files_company_level_api.rb +76 -0
  65. data/lib/adyen/services/management/api_credentials_company_level_api.rb +56 -0
  66. data/lib/adyen/services/management/api_credentials_merchant_level_api.rb +56 -0
  67. data/lib/adyen/services/management/api_key_company_level_api.rb +26 -0
  68. data/lib/adyen/services/management/api_key_merchant_level_api.rb +26 -0
  69. data/lib/adyen/services/management/client_key_company_level_api.rb +26 -0
  70. data/lib/adyen/services/management/client_key_merchant_level_api.rb +26 -0
  71. data/lib/adyen/services/management/my_api_credential_api.rb +76 -0
  72. data/lib/adyen/services/management/payment_methods_merchant_level_api.rb +76 -0
  73. data/lib/adyen/services/management/payout_settings_merchant_level_api.rb +66 -0
  74. data/lib/adyen/services/management/split_configuration_merchant_level_api.rb +106 -0
  75. data/lib/adyen/services/management/terminal_actions_company_level_api.rb +36 -0
  76. data/lib/adyen/services/management/terminal_actions_terminal_level_api.rb +26 -0
  77. data/lib/adyen/services/management/terminal_orders_company_level_api.rb +116 -0
  78. data/lib/adyen/services/management/terminal_orders_merchant_level_api.rb +116 -0
  79. data/lib/adyen/services/management/terminal_settings_company_level_api.rb +56 -0
  80. data/lib/adyen/services/management/terminal_settings_merchant_level_api.rb +56 -0
  81. data/lib/adyen/services/management/terminal_settings_store_level_api.rb +96 -0
  82. data/lib/adyen/services/management/terminal_settings_terminal_level_api.rb +56 -0
  83. data/lib/adyen/services/management/terminals_terminal_level_api.rb +36 -0
  84. data/lib/adyen/services/management/users_company_level_api.rb +56 -0
  85. data/lib/adyen/services/management/users_merchant_level_api.rb +56 -0
  86. data/lib/adyen/services/management/webhooks_company_level_api.rb +86 -0
  87. data/lib/adyen/services/management/webhooks_merchant_level_api.rb +86 -0
  88. data/lib/adyen/services/management.rb +164 -0
  89. data/lib/adyen/services/marketpay.rb +42 -36
  90. data/lib/adyen/services/payment.rb +149 -0
  91. data/lib/adyen/services/paymentsApp.rb +67 -0
  92. data/lib/adyen/services/payout/initialization_api.rb +46 -0
  93. data/lib/adyen/services/payout/instant_payouts_api.rb +26 -0
  94. data/lib/adyen/services/payout/reviewing_api.rb +36 -0
  95. data/lib/adyen/services/payout.rb +34 -0
  96. data/lib/adyen/services/posMobile.rb +27 -0
  97. data/lib/adyen/services/posTerminalManagement.rb +82 -0
  98. data/lib/adyen/services/recurring.rb +70 -13
  99. data/lib/adyen/services/service.rb +8 -2
  100. data/lib/adyen/services/storedValue.rb +77 -0
  101. data/lib/adyen/services/terminalCloudAPI.rb +38 -0
  102. data/lib/adyen/services/transfers/capital_api.rb +55 -0
  103. data/lib/adyen/services/transfers/transactions_api.rb +36 -0
  104. data/lib/adyen/services/transfers/transfers_api.rb +76 -0
  105. data/lib/adyen/services/transfers.rb +34 -0
  106. data/lib/adyen/utils/hmac_validator.rb +52 -22
  107. data/lib/adyen/version.rb +2 -2
  108. data/lib/adyen-ruby-api-library.rb +23 -15
  109. data/renovate.json +3 -3
  110. data/spec/account_spec.rb +20 -20
  111. data/spec/balance_control_spec.rb +43 -0
  112. data/spec/balance_platform_spec.rb +129 -0
  113. data/spec/bin_lookup_spec.rb +69 -11
  114. data/spec/checkout-oauth_spec.rb +588 -0
  115. data/spec/checkout_spec.rb +591 -314
  116. data/spec/client_spec.rb +240 -45
  117. data/spec/data_protection_spec.rb +4 -4
  118. data/spec/disputes_spec.rb +45 -0
  119. data/spec/errors_spec.rb +44 -15
  120. data/spec/fund_spec.rb +10 -10
  121. data/spec/hash_with_accessors_spec.rb +18 -8
  122. data/spec/hop_spec.rb +4 -4
  123. data/spec/lem_spec.rb +63 -0
  124. data/spec/management-oauth_spec.rb +62 -0
  125. data/spec/management_spec.rb +66 -0
  126. data/spec/mocks/requests/BalanceControl/balance_transfer.json +10 -0
  127. data/spec/mocks/requests/BalancePlatform/create_account_holder.json +5 -0
  128. data/spec/mocks/requests/BalancePlatform/update_account_holder.json +10 -0
  129. data/spec/mocks/requests/Checkout/amount_updates.json +22 -0
  130. data/spec/mocks/requests/Checkout/apple_pay_sessions.json +5 -0
  131. data/spec/mocks/requests/Checkout/capture.json +34 -0
  132. data/spec/mocks/requests/Checkout/generic_cancel.json +5 -0
  133. data/spec/mocks/requests/Checkout/modifications_request.json +0 -0
  134. data/spec/mocks/requests/Checkout/psp_cancel.json +4 -0
  135. data/spec/mocks/requests/Checkout/refund.json +34 -0
  136. data/spec/mocks/requests/DisputesService/retrieve_applicable_defense_reasons.json +4 -0
  137. data/spec/mocks/requests/LegalEntityManagement/create_business_line.json +15 -0
  138. data/spec/mocks/requests/Management/create_store.json +15 -0
  139. data/spec/mocks/requests/Recurring/create_permit.json +6 -0
  140. data/spec/mocks/requests/StoredValue/issue_giftcard.json +12 -0
  141. data/spec/mocks/requests/TerminalCloudAPI/connected_terminals.json +3 -0
  142. data/spec/mocks/requests/TerminalCloudAPI/sync_payment.json +29 -0
  143. data/spec/mocks/requests/Transfers/get_transactions.json +82 -0
  144. data/spec/mocks/requests/Transfers/make_transfer.json +32 -0
  145. data/spec/mocks/responses/BalanceControl/balance_transfer.json +14 -0
  146. data/spec/mocks/responses/BalancePlatform/create_account_holder.json +41 -0
  147. data/spec/mocks/responses/BalancePlatform/get_balance_account.json +15 -0
  148. data/spec/mocks/responses/BalancePlatform/update_account_holder.json +16 -0
  149. data/spec/mocks/responses/Checkout/amount_updates.json +24 -0
  150. data/spec/mocks/responses/Checkout/apple_pay_sessions.json +3 -0
  151. data/spec/mocks/responses/Checkout/capture.json +37 -0
  152. data/spec/mocks/responses/Checkout/generic_cancel.json +7 -0
  153. data/spec/mocks/responses/Checkout/modifications.json +0 -0
  154. data/spec/mocks/responses/Checkout/psp_cancel.json +7 -0
  155. data/spec/mocks/responses/Checkout/refund.json +37 -0
  156. data/spec/mocks/responses/Checkout/stored_payment_methods.json +1 -0
  157. data/spec/mocks/responses/DisputesService/retrieve_applicable_defense_reasons.json +71 -0
  158. data/spec/mocks/responses/LegalEntityManagement/create_business_line.json +17 -0
  159. data/spec/mocks/responses/Management/create_store.json +23 -0
  160. data/spec/mocks/responses/Management/get_companies.json +42 -0
  161. data/spec/mocks/responses/Recurring/create_permit.json +4 -0
  162. data/spec/mocks/responses/StoredValue/issue_giftcard.json +13 -0
  163. data/spec/mocks/responses/TerminalCloudAPI/connected_terminals.json +5 -0
  164. data/spec/mocks/responses/TerminalCloudAPI/sync_payment.json +18 -0
  165. data/spec/mocks/responses/Transfers/get_transactions.json +82 -0
  166. data/spec/mocks/responses/Transfers/make_transfer.json +36 -0
  167. data/spec/mocks/responses/Webhooks/backslash_webhook.json +41 -0
  168. data/spec/mocks/responses/Webhooks/colon_webhook.json +41 -0
  169. data/spec/mocks/responses/Webhooks/forwardslash_webhook.json +41 -0
  170. data/spec/mocks/responses/Webhooks/mixed_webhook.json +41 -0
  171. data/spec/notification_spec.rb +9 -9
  172. data/spec/payments_spec.rb +39 -22
  173. data/spec/payouts_spec.rb +39 -15
  174. data/spec/pos_terminal_management_spec.rb +44 -0
  175. data/spec/recurring_spec.rb +8 -8
  176. data/spec/service_spec.rb +4 -0
  177. data/spec/spec_helper.rb +42 -46
  178. data/spec/stored_value_spec.rb +44 -0
  179. data/spec/terminal_cloud_api_spec.rb +91 -0
  180. data/spec/transfers_spec.rb +64 -0
  181. data/spec/utils/hmac_validator_spec.rb +53 -23
  182. data/templates/api-single.mustache +32 -0
  183. data/templates/api-small.mustache +39 -0
  184. data/templates/api.mustache +38 -0
  185. data/templates/config.yaml +10 -0
  186. metadata +160 -47
  187. data/.github/dependabot.yml +0 -8
  188. data/docs/checkout.html +0 -128
  189. data/docs/index.html +0 -50
  190. data/docs/install-library.html +0 -61
  191. data/docs/javascripts/prism.js +0 -5
  192. data/docs/javascripts/scale.fix.js +0 -17
  193. data/docs/marketpay.html +0 -171
  194. data/docs/params.json +0 -1
  195. data/docs/payment.html +0 -106
  196. data/docs/payout.html +0 -135
  197. data/docs/recurring.html +0 -113
  198. data/docs/stylesheets/github-light.css +0 -115
  199. data/docs/stylesheets/prism.css +0 -140
  200. data/docs/stylesheets/styles.css +0 -324
  201. data/docs/using-library.html +0 -67
  202. data/lib/adyen/services/bin_lookup.rb +0 -18
  203. data/lib/adyen/services/data_protection.rb +0 -17
  204. data/lib/adyen/services/dispute.rb +0 -20
  205. data/lib/adyen/services/payments.rb +0 -34
  206. data/lib/adyen/services/payouts.rb +0 -22
  207. data/lib/adyen/services/postfmapi.rb +0 -19
  208. data/spec/dispute_spec.rb +0 -17
  209. data/spec/mocks/requests/DisputeService/defend_dispute.json +0 -5
  210. data/spec/mocks/requests/DisputeService/delete_dispute_defense_document.json +0 -5
  211. data/spec/mocks/requests/DisputeService/retrieve_applicable_defense_reasons.json +0 -4
  212. data/spec/mocks/requests/DisputeService/supply_defense_document.json +0 -11
  213. data/spec/mocks/requests/Recurring/store_token.json +0 -15
  214. data/spec/mocks/responses/DisputeService/defend_dispute.json +0 -5
  215. data/spec/mocks/responses/DisputeService/delete_dispute_defense_document.json +0 -5
  216. data/spec/mocks/responses/DisputeService/retrieve_applicable_defense_reasons.json +0 -28
  217. data/spec/mocks/responses/DisputeService/supply_defense_document.json +0 -5
  218. data/spec/mocks/responses/Recurring/store_token.json +0 -7
  219. data/spec/postfmapi_spec.rb +0 -16
data/lib/adyen/client.rb CHANGED
@@ -1,187 +1,225 @@
1
- require "faraday"
2
- require "json"
3
- require_relative "./errors"
4
- require_relative "./result"
1
+ # rubocop:disable Metrics/ParameterLists
2
+ # rubocop:disable Metrics/PerceivedComplexity
3
+ # rubocop:disable Metrics/MethodLength
4
+ # rubocop:disable Metrics/CyclomaticComplexity
5
+ # rubocop:disable Metrics/AbcSize
6
+ # rubocop:disable Metrics/ClassLength
7
+
8
+ require 'faraday'
9
+ require 'json'
10
+ require_relative './errors'
11
+ require_relative './result'
5
12
 
6
13
  module Adyen
7
14
  class Client
8
- attr_accessor :ws_user, :ws_password, :api_key, :client, :adapter, :live_url_prefix
9
- attr_reader :env
15
+ attr_accessor :ws_user, :ws_password, :api_key, :oauth_token, :client, :adapter
16
+ attr_reader :env, :connection_options, :adapter_options, :terminal_region
10
17
 
11
- def initialize(ws_user: nil, ws_password: nil, api_key: nil, env: :live, adapter: nil, mock_port: 3001, live_url_prefix: nil, mock_service_url_base: nil)
18
+ def initialize(ws_user: nil, ws_password: nil, api_key: nil, oauth_token: nil, env: :live, adapter: nil, mock_port: 3001,
19
+ live_url_prefix: nil, mock_service_url_base: nil, connection_options: nil, adapter_options: nil, terminal_region: nil)
12
20
  @ws_user = ws_user
13
21
  @ws_password = ws_password
14
22
  @api_key = api_key
23
+ @oauth_token = oauth_token
15
24
  @env = env
16
25
  @adapter = adapter || Faraday.default_adapter
26
+ if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.1')
27
+ # for faraday 2.1 and higher
28
+ @adapter_options = adapter_options || Faraday.default_adapter_options
29
+ else
30
+ # for faraday 1.x and 2.0
31
+ @adapter_options = adapter_options || {}
32
+ end
17
33
  @mock_service_url_base = mock_service_url_base || "http://localhost:#{mock_port}"
18
34
  @live_url_prefix = live_url_prefix
35
+ @connection_options = connection_options || Faraday::ConnectionOptions.new
36
+ @terminal_region = terminal_region
19
37
  end
20
38
 
21
39
  # make sure that env can only be :live, :test, or :mock
22
40
  def env=(value)
23
- raise ArgumentError, "Invalid value for Client.env: '#{value}'' - must be one of [:live, :test, :mock]" unless [:live, :test, :mock].include? value
41
+ raise ArgumentError, "Invalid value for Client.env: '#{value}'' - must be one of [:live, :test, :mock]" unless %i[
42
+ live test mock
43
+ ].include? value
44
+
24
45
  @env = value
25
46
  end
26
47
 
27
48
  # remove 'https' from live_url_prefix if necessary
28
49
  def live_url_prefix=(value)
29
- if not value["https://"].nil?
30
- value["https://"] = ""
31
- end
50
+ value['https://'] = '' unless value['https://'].nil?
32
51
  @live_url_prefix = value
33
52
  end
34
53
 
35
54
  # base URL for API given service and @env
36
55
  def service_url_base(service)
37
- raise ArgumentError, "Please set Client.live_url_prefix to the portion of your merchant-specific URL prior to '-[service]-live.adyenpayments.com'" if @live_url_prefix.nil? and @env == :live
38
56
  if @env == :mock
39
57
  @mock_service_url_base
40
58
  else
41
59
  case service
42
- when "Checkout"
43
- url = "https://checkout-#{@env}.adyen.com/checkout"
60
+ when 'Checkout'
61
+ url = "https://checkout-#{@env}.adyen.com"
44
62
  supports_live_url_prefix = true
45
- when "Account", "Fund", "Notification", "Hop"
46
- url = "https://cal-#{@env}.adyen.com/cal/services"
63
+ when 'Account', 'Fund', 'Notification', 'Hop'
64
+ url = "https://cal-#{@env}.adyen.com/cal/services/#{service}"
47
65
  supports_live_url_prefix = false
48
- when "Recurring", "Payment", "Payout", "BinLookup"
49
- url = "https://pal-#{@env}.adyen.com/pal/servlet"
66
+ when 'Recurring', 'Payment', 'Payout', 'BinLookup', 'StoredValue', 'BalanceControlService'
67
+ url = "https://pal-#{@env}.adyen.com/pal/servlet/#{service}"
50
68
  supports_live_url_prefix = true
51
- when "Terminal"
69
+ when 'PosTerminalManagement'
52
70
  url = "https://postfmapi-#{@env}.adyen.com/postfmapi/terminal"
53
71
  supports_live_url_prefix = false
54
- when "DataProtectionService", "DisputeService"
55
- url = "https://ca-#{@env}.adyen.com/ca/services"
72
+ when 'DataProtectionService', 'DisputesService'
73
+ url = "https://ca-#{@env}.adyen.com/ca/services/#{service}"
74
+ supports_live_url_prefix = false
75
+ when 'LegalEntityManagement'
76
+ url = "https://kyc-#{@env}.adyen.com/lem"
77
+ supports_live_url_prefix = false
78
+ when 'BalancePlatform'
79
+ url = "https://balanceplatform-api-#{@env}.adyen.com/bcl"
80
+ supports_live_url_prefix = false
81
+ when 'Transfers'
82
+ url = "https://balanceplatform-api-#{@env}.adyen.com/btl"
83
+ supports_live_url_prefix = false
84
+ when 'Management'
85
+ url = "https://management-#{@env}.adyen.com"
56
86
  supports_live_url_prefix = false
87
+ when 'TerminalCloudAPI'
88
+ url = if !terminal_region.nil?
89
+ "https://terminal-api-#{@env}-#{terminal_region}.adyen.com"
90
+ else
91
+ "https://terminal-api-#{@env}.adyen.com"
92
+ end
93
+ supports_live_url_prefix = false
94
+ when 'PosMobile'
95
+ url = "https://checkout-#{@env}.adyen.com/checkout/possdk"
96
+ supports_live_url_prefix = true
57
97
  else
58
- raise ArgumentError, "Invalid service specified"
98
+ raise ArgumentError, 'Invalid service specified'
99
+ end
100
+
101
+ if @live_url_prefix.nil? && (@env == :live) && supports_live_url_prefix
102
+ raise ArgumentError,
103
+ "Please set Client.live_url_prefix to the portion \
104
+ of your merchant-specific URL prior to '-[service]-live.adyenpayments.com'"
59
105
  end
60
106
 
61
107
  if @env == :live && supports_live_url_prefix
62
108
  url.insert(8, "#{@live_url_prefix}-")
63
- url["adyen.com"] = "adyenpayments.com"
109
+ url['adyen.com'] = 'adyenpayments.com'
64
110
  end
65
111
 
66
- return url
112
+ url
67
113
  end
68
114
  end
69
115
 
70
116
  # construct full URL from service and endpoint
71
117
  def service_url(service, action, version)
72
- if service == "Checkout" || service == "Terminal"
73
- "#{service_url_base(service)}/v#{version}/#{action}"
118
+ if service == "Checkout" && @env == :live
119
+ return "#{service_url_base(service)}/checkout/v#{version}/#{action}"
120
+ elsif version == nil
121
+ return "#{service_url_base(service)}/#{action}"
74
122
  else
75
- "#{service_url_base(service)}/#{service}/v#{version}/#{action}"
123
+ return "#{service_url_base(service)}/v#{version}/#{action}"
76
124
  end
77
125
  end
78
126
 
79
127
  # send request to adyen API
80
- def call_adyen_api(service, action, request_data, headers, version, with_application_info = false)
128
+ def call_adyen_api(service, action, request_data, headers, version, _with_application_info: false)
81
129
  # get URL for requested endpoint
82
130
  url = service_url(service, action.is_a?(String) ? action : action.fetch(:url), version)
83
131
 
84
- # make sure right authentication has been provided
85
- # will use api_key if present, otherwise ws_user and ws_password
86
- if @api_key.nil?
87
- if service == "PaymentSetupAndVerification"
88
- raise Adyen::AuthenticationError.new("Checkout service requires API-key", request_data), "Checkout service requires API-key"
89
- elsif @ws_password.nil? || @ws_user.nil?
90
- raise Adyen::AuthenticationError.new("No authentication found - please set api_key or ws_user and ws_password", request_data), "No authentication found - please set api_key or ws_user and ws_password"
91
- else
92
- auth_type = "basic"
93
- end
94
- else
95
- auth_type = "api-key"
96
- end
132
+ auth_type = auth_type(service, request_data)
97
133
 
98
134
  # initialize Faraday connection object
99
- conn = Faraday.new(url: url) do |faraday|
100
- faraday.adapter @adapter
101
- faraday.headers["Content-Type"] = "application/json"
102
- faraday.headers["User-Agent"] = Adyen::NAME + "/" + Adyen::VERSION
103
-
104
- # set auth type based on service
105
- case auth_type
106
- when "basic"
107
- faraday.basic_auth(@ws_user, @ws_password)
108
- when "api-key"
109
- faraday.headers["x-api-key"] = @api_key
110
- end
135
+ conn = Faraday.new(url, @connection_options) do |faraday|
136
+ faraday.adapter @adapter, **@adapter_options
137
+ faraday.headers['Content-Type'] = 'application/json'
138
+ faraday.headers['User-Agent'] = "#{Adyen::NAME}/#{Adyen::VERSION}"
139
+
140
+ # set header based on auth_type and service
141
+ auth_header(auth_type, faraday)
111
142
 
112
143
  # add optional headers if specified in request
113
144
  # will overwrite default headers if overlapping
114
145
  headers.map do |key, value|
115
146
  faraday.headers[key] = value
116
147
  end
148
+
149
+ # add library headers
150
+ faraday.headers['adyen-library-name'] = Adyen::NAME
151
+ faraday.headers['adyen-library-version'] = Adyen::VERSION
117
152
  end
118
153
  # if json string convert to hash
119
154
  # needed to add applicationInfo
120
- if request_data.is_a?(String)
121
- request_data = JSON.parse(request_data)
122
- end
123
-
124
- # add application only on checkout service
125
- if with_application_info
126
- add_application_info(request_data)
127
- end
155
+ request_data = JSON.parse(request_data) if request_data.is_a?(String)
128
156
 
129
157
  # convert to json
130
158
  request_data = request_data.to_json
131
159
 
132
160
  if action.is_a?(::Hash)
133
- if action.fetch(:method) == "get"
161
+ if action.fetch(:method) == 'get'
134
162
  begin
135
- response = conn.get
136
- rescue Faraday::ConnectionFailed => connection_error
137
- raise connection_error, "Connection to #{url} failed"
163
+ response = conn.get
164
+ rescue Faraday::ConnectionFailed => e
165
+ raise e, "Connection to #{url} failed"
138
166
  end
139
167
  end
140
- if action.fetch(:method) == "patch"
168
+ if action.fetch(:method) == 'delete'
169
+ begin
170
+ response = conn.delete
171
+ rescue Faraday::ConnectionFailed => e
172
+ raise e, "Connection to #{url} failed"
173
+ end
174
+ end
175
+ if action.fetch(:method) == 'patch'
141
176
  begin
142
177
  response = conn.patch do |req|
143
178
  req.body = request_data
144
179
  end
145
- rescue Faraday::ConnectionFailed => connection_error
146
- raise connection_error, "Connection to #{url} failed"
180
+ rescue Faraday::ConnectionFailed => e
181
+ raise e, "Connection to #{url} failed"
182
+ end
183
+ end
184
+ if action.fetch(:method) == 'post'
185
+ # post request to Adyen
186
+ begin
187
+ response = conn.post do |req|
188
+ req.body = request_data
189
+ end
190
+ rescue Faraday::ConnectionFailed => e
191
+ raise e, "Connection to #{url} failed"
147
192
  end
148
193
  end
149
194
  else
150
- # post request to Adyen
151
195
  begin
152
196
  response = conn.post do |req|
153
197
  req.body = request_data
154
- end # handle client errors
155
- rescue Faraday::ConnectionFailed => connection_error
156
- raise connection_error, "Connection to #{url} failed"
198
+ end
199
+ rescue Faraday::ConnectionFailed => e
200
+ raise e, "Connection to #{url} failed"
157
201
  end
158
202
  end
159
-
160
203
  # check for API errors
161
204
  case response.status
162
205
  when 401
163
- raise Adyen::AuthenticationError.new("Invalid API authentication; https://docs.adyen.com/user-management/how-to-get-the-api-key", request_data)
206
+ raise Adyen::AuthenticationError.new(
207
+ 'Invalid API authentication; https://docs.adyen.com/user-management/how-to-get-the-api-key', request_data
208
+ )
164
209
  when 403
165
- raise Adyen::PermissionError.new("Missing user permissions; https://docs.adyen.com/user-management/user-roles", request_data)
210
+ raise Adyen::PermissionError.new('Missing user permissions; https://docs.adyen.com/user-management/user-roles',
211
+ request_data, response.body)
166
212
  end
167
213
 
168
- formatted_response = AdyenResult.new(response.body, response.headers, response.status)
169
-
170
- formatted_response
171
- end
172
-
173
- # add application_info for analytics
174
- def add_application_info(request_data)
175
- adyenLibrary = {
176
- :name => Adyen::NAME,
177
- :version => Adyen::VERSION.to_s,
178
- }
179
-
180
- if request_data[:applicationInfo].nil?
181
- request_data[:applicationInfo] = {}
214
+ # delete has no response.body (unless it throws an error)
215
+ if response.body.nil? || response.body === ''
216
+ AdyenResult.new('{}', response.headers, response.status)
217
+ # terminal API async call returns always 'ok'
218
+ elsif response.body === 'ok'
219
+ AdyenResult.new('{}', response.headers, response.status)
220
+ else
221
+ AdyenResult.new(response.body, response.headers, response.status)
182
222
  end
183
-
184
- request_data[:applicationInfo][:adyenLibrary] = adyenLibrary
185
223
  end
186
224
 
187
225
  # services
@@ -189,12 +227,12 @@ module Adyen
189
227
  @checkout ||= Adyen::Checkout.new(self)
190
228
  end
191
229
 
192
- def payments
193
- @payments ||= Adyen::Payments.new(self)
230
+ def payment
231
+ @payment ||= Adyen::Payment.new(self)
194
232
  end
195
233
 
196
- def payouts
197
- @payouts ||= Adyen::Payouts.new(self)
234
+ def payout
235
+ @payout ||= Adyen::Payout.new(self)
198
236
  end
199
237
 
200
238
  def recurring
@@ -205,20 +243,96 @@ module Adyen
205
243
  @marketpay ||= Adyen::Marketpay::Marketpay.new(self)
206
244
  end
207
245
 
208
- def postfmapi
209
- @postfmapi ||= Adyen::PosTerminalManagement.new(self)
246
+ def pos_terminal_management
247
+ @pos_terminal_management ||= Adyen::PosTerminalManagement.new(self)
210
248
  end
211
249
 
212
250
  def data_protection
213
251
  @data_protection ||= Adyen::DataProtection.new(self)
214
252
  end
215
253
 
216
- def dispute
217
- @dispute ||= Adyen::Dispute.new(self)
254
+ def disputes
255
+ @disputes ||= Adyen::Disputes.new(self)
218
256
  end
219
257
 
220
258
  def bin_lookup
221
259
  @bin_lookup ||= Adyen::BinLookup.new(self)
222
260
  end
261
+
262
+ def legal_entity_management
263
+ @legal_entity_management ||= Adyen::LegalEntityManagement.new(self)
264
+ end
265
+
266
+ def balance_platform
267
+ @balance_platform ||= Adyen::BalancePlatform.new(self)
268
+ end
269
+
270
+ def transfers
271
+ @transfers ||= Adyen::Transfers.new(self)
272
+ end
273
+
274
+ def management
275
+ @management ||= Adyen::Management.new(self)
276
+ end
277
+
278
+ def stored_value
279
+ @stored_value ||= Adyen::StoredValue.new(self)
280
+ end
281
+
282
+ def balance_control_service
283
+ @balance_control_service ||= Adyen::BalanceControlService.new(self)
284
+ end
285
+
286
+ def terminal_cloud_api
287
+ @terminal_cloud_api ||= Adyen::TerminalCloudAPI.new(self)
288
+ end
289
+
290
+ def pos_mobile
291
+ @pos_mobile ||= Adyen::PosMobile.new(self)
292
+ end
293
+
294
+ private
295
+
296
+ def auth_header(auth_type, faraday)
297
+ case auth_type
298
+ when "basic"
299
+ if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
300
+ # for faraday 2.0 and higher
301
+ faraday.request :authorization, :basic, @ws_user, @ws_password
302
+ else
303
+ # for faraday 1.x
304
+ faraday.basic_auth(@ws_user, @ws_password)
305
+ end
306
+ when "api-key"
307
+ faraday.headers["x-api-key"] = @api_key
308
+ when "oauth"
309
+ faraday.headers["Authorization"] = "Bearer #{@oauth_token}"
310
+ end
311
+ end
312
+
313
+ def auth_type(service, request_data)
314
+ # make sure valid authentication has been provided
315
+ validate_auth_type(service, request_data)
316
+ # Will prioritize authentication methods in this order:
317
+ # api-key, oauth, basic
318
+ return "api-key" unless @api_key.nil?
319
+ return "oauth" unless @oauth_token.nil?
320
+ "basic"
321
+ end
322
+
323
+ def validate_auth_type(service, request_data)
324
+ # ensure authentication has been provided
325
+ if @api_key.nil? && @oauth_token.nil? && (@ws_password.nil? || @ws_user.nil?)
326
+ raise Adyen::AuthenticationError.new(
327
+ 'No authentication found - please set api_key, oauth_token, or ws_user and ws_password',
328
+ request_data
329
+ )
330
+ end
331
+ if service == "PaymentSetupAndVerification" && @api_key.nil? && @oauth_token.nil? && @ws_password.nil? && @ws_user.nil?
332
+ raise Adyen::AuthenticationError.new('Checkout service requires API-key or oauth_token', request_data),
333
+ 'Checkout service requires API-key or oauth_token'
334
+ end
335
+ end
223
336
  end
224
337
  end
338
+ # rubocop:enable all
data/lib/adyen/errors.rb CHANGED
@@ -1,9 +1,18 @@
1
+ # rubocop:disable Metrics/AbcSize
2
+ # rubocop:disable Metrics/MethodLength
3
+ # rubocop:disable Metrics/PerceivedComplexity
4
+ # rubocop:disable Metrics/CyclomaticComplexity
5
+ # rubocop:disable Metrics/ParameterLists
6
+
1
7
  module Adyen
2
8
  class AdyenError < StandardError
3
9
  attr_reader :code, :response, :request, :msg
4
10
 
5
11
  def initialize(request = nil, response = nil, msg = nil, code = nil)
6
- mask_fields(request)
12
+ unless request.nil?
13
+ request = request.is_a?(Hash) ? request : JSON.parse(request, symbolize_names: true)
14
+ mask_fields(request)
15
+ end
7
16
 
8
17
  # components of formatted error message
9
18
  attributes = {
@@ -27,34 +36,32 @@ module Adyen
27
36
  return if request.nil?
28
37
 
29
38
  # sensitive fields
30
- fields_to_mask = [
31
- :expiryMonth,
32
- :expiryYear,
33
- :encryptedCardNumber,
34
- :encryptedExpiryMonth,
35
- :encryptedExpiryYear,
36
- :encryptedSecurityCode
39
+ fields_to_mask = %i[
40
+ expiryMonth
41
+ expiryYear
42
+ encryptedCardNumber
43
+ encryptedExpiryMonth
44
+ encryptedExpiryYear
45
+ encryptedSecurityCode
37
46
  ]
38
47
 
39
48
  # convert to hash if necessary
40
- request = request.is_a?(Hash) ? request : JSON.parse(request)
49
+ request = request.is_a?(Hash) ? request : JSON.parse(request, symbolize_names: true)
41
50
 
42
51
  # iterate through request to find fields to mask
43
52
  request.each do |k, v|
44
53
  if request[k].is_a?(Hash)
45
54
  # recursively traverse multi-level hashes
46
55
  mask_fields(request[k])
47
- else
48
- if k == :number
49
- # show first 6 and last 4 for cards
50
- request[k] = "#{v[0,6]}******#{v[12,16]}"
51
- elsif k == :cvc
52
- # show length of cvc for debugging
53
- request[k] = "*" * v.length
54
- elsif fields_to_mask.include? k
55
- # generic mask for other fields
56
- request[k] = "***"
57
- end
56
+ elsif k == :number
57
+ request[k] = "#{v[0, 6]}******#{v[12, 16]}"
58
+ # show first 6 and last 4 for cards
59
+ elsif k == :cvc
60
+ # show length of cvc for debugging
61
+ request[k] = '*' * v.length
62
+ elsif fields_to_mask.include? k
63
+ # generic mask for other fields
64
+ request[k] = '***'
58
65
  end
59
66
  end
60
67
  end
@@ -67,8 +74,8 @@ module Adyen
67
74
  end
68
75
 
69
76
  class PermissionError < AdyenError
70
- def initialize(msg, request)
71
- super(request, nil, msg, 403)
77
+ def initialize(msg, request, response)
78
+ super(request, response, msg, 403)
72
79
  end
73
80
  end
74
81
 
@@ -103,3 +110,4 @@ module Adyen
103
110
  end
104
111
  end
105
112
  end
113
+ # rubocop:enable all
@@ -1,3 +1,7 @@
1
+ # rubocop:disable Metrics/AbcSize
2
+ # rubocop:disable Metrics/MethodLength
3
+ # rubocop:disable Metrics/PerceivedComplexity
4
+
1
5
  # This utility method inherits from Hash, but allows keys to be read
2
6
  # and updated with dot notation. Usage is entirely optional (i.e., hash values
3
7
  # can still be accessed via symbol and string keys).
@@ -9,11 +13,11 @@ module Adyen
9
13
  string_key = method.to_s.sub(/=\z/, '')
10
14
  sym_key = string_key.to_sym
11
15
 
12
- key = if has_key?(string_key)
13
- string_key
14
- elsif has_key?(sym_key)
15
- sym_key
16
- end
16
+ key = if key?(string_key)
17
+ string_key
18
+ elsif key?(sym_key)
19
+ sym_key
20
+ end
17
21
 
18
22
  return super unless key
19
23
 
@@ -24,7 +28,7 @@ module Adyen
24
28
 
25
29
  self[key] = args.first
26
30
  else
27
- raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0)" unless args.size == 0
31
+ raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0)" unless args.empty?
28
32
 
29
33
  self[key]
30
34
  end
@@ -32,7 +36,8 @@ module Adyen
32
36
 
33
37
  def respond_to_missing?(method, include_private = false)
34
38
  string_key = method.to_s.sub(/=\z/, '')
35
- has_key?(string_key) || has_key?(string_key.to_sym) || super
39
+ key?(string_key) || key?(string_key.to_sym) || super
36
40
  end
37
41
  end
38
42
  end
43
+ # rubocop:enable all
@@ -0,0 +1,27 @@
1
+ require_relative './service'
2
+ module Adyen
3
+
4
+ # NOTE: This class is auto generated by OpenAPI Generator
5
+ # Ref: https://openapi-generator.tech
6
+ #
7
+ # Do not edit the class manually.
8
+ class BalanceControlService < Service
9
+ attr_accessor :service, :version
10
+
11
+ DEFAULT_VERSION = 1
12
+ def initialize(client, version = DEFAULT_VERSION)
13
+ super(client, version, 'BalanceControlService')
14
+ end
15
+
16
+ # Start a balance transfer
17
+ def balance_transfer(request, headers: {})
18
+ endpoint = '/balanceTransfer'.gsub(/{.+?}/, '%s')
19
+ endpoint = endpoint.gsub(%r{^/}, '')
20
+ endpoint = format(endpoint)
21
+
22
+ action = { method: 'post', url: endpoint }
23
+ @client.call_adyen_api(@service, action, request, headers, @version)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,76 @@
1
+ require_relative '../service'
2
+ module Adyen
3
+
4
+ # NOTE: This class is auto generated by OpenAPI Generator
5
+ # Ref: https://openapi-generator.tech
6
+ #
7
+ # Do not edit the class manually.
8
+ class AccountHoldersApi < Service
9
+ attr_accessor :service, :version
10
+
11
+ def initialize(client, version = DEFAULT_VERSION)
12
+ super(client, version, 'BalancePlatform')
13
+ end
14
+
15
+ # Create an account holder
16
+ def create_account_holder(request, headers: {})
17
+ endpoint = '/accountHolders'.gsub(/{.+?}/, '%s')
18
+ endpoint = endpoint.gsub(%r{^/}, '')
19
+ endpoint = format(endpoint)
20
+
21
+ action = { method: 'post', url: endpoint }
22
+ @client.call_adyen_api(@service, action, request, headers, @version)
23
+ end
24
+
25
+ # Get an account holder
26
+ def get_account_holder(id, headers: {})
27
+ endpoint = '/accountHolders/{id}'.gsub(/{.+?}/, '%s')
28
+ endpoint = endpoint.gsub(%r{^/}, '')
29
+ endpoint = format(endpoint, id)
30
+
31
+ action = { method: 'get', url: endpoint }
32
+ @client.call_adyen_api(@service, action, {}, headers, @version)
33
+ end
34
+
35
+ # Get all balance accounts of an account holder
36
+ def get_all_balance_accounts_of_account_holder(id, headers: {}, query_params: {})
37
+ endpoint = '/accountHolders/{id}/balanceAccounts'.gsub(/{.+?}/, '%s')
38
+ endpoint = endpoint.gsub(%r{^/}, '')
39
+ endpoint = format(endpoint, id)
40
+ endpoint += create_query_string(query_params)
41
+ action = { method: 'get', url: endpoint }
42
+ @client.call_adyen_api(@service, action, {}, headers, @version)
43
+ end
44
+
45
+ # Get all transaction rules for an account holder
46
+ def get_all_transaction_rules_for_account_holder(id, headers: {})
47
+ endpoint = '/accountHolders/{id}/transactionRules'.gsub(/{.+?}/, '%s')
48
+ endpoint = endpoint.gsub(%r{^/}, '')
49
+ endpoint = format(endpoint, id)
50
+
51
+ action = { method: 'get', url: endpoint }
52
+ @client.call_adyen_api(@service, action, {}, headers, @version)
53
+ end
54
+
55
+ # Get a tax form
56
+ def get_tax_form(id, headers: {}, query_params: {})
57
+ endpoint = '/accountHolders/{id}/taxForms'.gsub(/{.+?}/, '%s')
58
+ endpoint = endpoint.gsub(%r{^/}, '')
59
+ endpoint = format(endpoint, id)
60
+ endpoint += create_query_string(query_params)
61
+ action = { method: 'get', url: endpoint }
62
+ @client.call_adyen_api(@service, action, {}, headers, @version)
63
+ end
64
+
65
+ # Update an account holder
66
+ def update_account_holder(request, id, headers: {})
67
+ endpoint = '/accountHolders/{id}'.gsub(/{.+?}/, '%s')
68
+ endpoint = endpoint.gsub(%r{^/}, '')
69
+ endpoint = format(endpoint, id)
70
+
71
+ action = { method: 'patch', url: endpoint }
72
+ @client.call_adyen_api(@service, action, request, headers, @version)
73
+ end
74
+
75
+ end
76
+ end