direct-sdk-ruby 1.0.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 (238) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +141 -0
  5. data/Rakefile +34 -0
  6. data/direct-sdk-ruby.gemspec +28 -0
  7. data/lib/ingenico/direct/sdk.rb +26 -0
  8. data/lib/ingenico/direct/sdk/api_exception.rb +42 -0
  9. data/lib/ingenico/direct/sdk/api_resource.rb +115 -0
  10. data/lib/ingenico/direct/sdk/authenticator.rb +16 -0
  11. data/lib/ingenico/direct/sdk/authorization_exception.rb +13 -0
  12. data/lib/ingenico/direct/sdk/call_context.rb +26 -0
  13. data/lib/ingenico/direct/sdk/client.rb +85 -0
  14. data/lib/ingenico/direct/sdk/communication_exception.rb +16 -0
  15. data/lib/ingenico/direct/sdk/communicator.rb +301 -0
  16. data/lib/ingenico/direct/sdk/communicator_configuration.rb +59 -0
  17. data/lib/ingenico/direct/sdk/connection.rb +41 -0
  18. data/lib/ingenico/direct/sdk/data_object.rb +32 -0
  19. data/lib/ingenico/direct/sdk/declined_payment_exception.rb +30 -0
  20. data/lib/ingenico/direct/sdk/declined_payout_exception.rb +32 -0
  21. data/lib/ingenico/direct/sdk/declined_refund_exception.rb +32 -0
  22. data/lib/ingenico/direct/sdk/declined_transaction_exception.rb +16 -0
  23. data/lib/ingenico/direct/sdk/defaultimpl.rb +6 -0
  24. data/lib/ingenico/direct/sdk/defaultimpl/authorization_type.rb +24 -0
  25. data/lib/ingenico/direct/sdk/defaultimpl/default_authenticator.rb +108 -0
  26. data/lib/ingenico/direct/sdk/defaultimpl/default_connection.rb +293 -0
  27. data/lib/ingenico/direct/sdk/defaultimpl/default_marshaller.rb +32 -0
  28. data/lib/ingenico/direct/sdk/direct_exception.rb +15 -0
  29. data/lib/ingenico/direct/sdk/domain/account_on_file.rb +50 -0
  30. data/lib/ingenico/direct/sdk/domain/account_on_file_attribute.rb +39 -0
  31. data/lib/ingenico/direct/sdk/domain/account_on_file_display_hints.rb +38 -0
  32. data/lib/ingenico/direct/sdk/domain/additional_order_input.rb +47 -0
  33. data/lib/ingenico/direct/sdk/domain/address.rb +51 -0
  34. data/lib/ingenico/direct/sdk/domain/address_personal.rb +59 -0
  35. data/lib/ingenico/direct/sdk/domain/airline_data.rb +129 -0
  36. data/lib/ingenico/direct/sdk/domain/airline_flight_leg.rb +99 -0
  37. data/lib/ingenico/direct/sdk/domain/airline_passenger.rb +39 -0
  38. data/lib/ingenico/direct/sdk/domain/amount_breakdown.rb +31 -0
  39. data/lib/ingenico/direct/sdk/domain/amount_of_money.rb +31 -0
  40. data/lib/ingenico/direct/sdk/domain/api_error.rb +47 -0
  41. data/lib/ingenico/direct/sdk/domain/browser_data.rb +39 -0
  42. data/lib/ingenico/direct/sdk/domain/cancel_payment_response.rb +31 -0
  43. data/lib/ingenico/direct/sdk/domain/capture.rb +47 -0
  44. data/lib/ingenico/direct/sdk/domain/capture_output.rb +79 -0
  45. data/lib/ingenico/direct/sdk/domain/capture_payment_request.rb +31 -0
  46. data/lib/ingenico/direct/sdk/domain/capture_response.rb +47 -0
  47. data/lib/ingenico/direct/sdk/domain/capture_status_output.rb +27 -0
  48. data/lib/ingenico/direct/sdk/domain/captures_response.rb +34 -0
  49. data/lib/ingenico/direct/sdk/domain/card.rb +39 -0
  50. data/lib/ingenico/direct/sdk/domain/card_essentials.rb +31 -0
  51. data/lib/ingenico/direct/sdk/domain/card_fraud_results.rb +35 -0
  52. data/lib/ingenico/direct/sdk/domain/card_payment_method_specific_input.rb +95 -0
  53. data/lib/ingenico/direct/sdk/domain/card_payment_method_specific_input_base.rb +79 -0
  54. data/lib/ingenico/direct/sdk/domain/card_payment_method_specific_output.rb +67 -0
  55. data/lib/ingenico/direct/sdk/domain/card_payout_method_specific_input.rb +39 -0
  56. data/lib/ingenico/direct/sdk/domain/card_recurrence_details.rb +27 -0
  57. data/lib/ingenico/direct/sdk/domain/card_without_cvv.rb +35 -0
  58. data/lib/ingenico/direct/sdk/domain/company_information.rb +27 -0
  59. data/lib/ingenico/direct/sdk/domain/complete_payment_card_payment_method_specific_input.rb +31 -0
  60. data/lib/ingenico/direct/sdk/domain/complete_payment_request.rb +39 -0
  61. data/lib/ingenico/direct/sdk/domain/complete_payment_response.rb +47 -0
  62. data/lib/ingenico/direct/sdk/domain/contact_details.rb +43 -0
  63. data/lib/ingenico/direct/sdk/domain/create_hosted_checkout_request.rb +63 -0
  64. data/lib/ingenico/direct/sdk/domain/create_hosted_checkout_response.rb +49 -0
  65. data/lib/ingenico/direct/sdk/domain/create_hosted_tokenization_request.rb +39 -0
  66. data/lib/ingenico/direct/sdk/domain/create_hosted_tokenization_response.rb +41 -0
  67. data/lib/ingenico/direct/sdk/domain/create_payment_request.rb +67 -0
  68. data/lib/ingenico/direct/sdk/domain/create_payment_response.rb +47 -0
  69. data/lib/ingenico/direct/sdk/domain/create_payout_request.rb +47 -0
  70. data/lib/ingenico/direct/sdk/domain/create_token_request.rb +35 -0
  71. data/lib/ingenico/direct/sdk/domain/created_payment_output.rb +35 -0
  72. data/lib/ingenico/direct/sdk/domain/created_token_response.rb +51 -0
  73. data/lib/ingenico/direct/sdk/domain/customer.rb +87 -0
  74. data/lib/ingenico/direct/sdk/domain/customer_account.rb +71 -0
  75. data/lib/ingenico/direct/sdk/domain/customer_account_authentication.rb +31 -0
  76. data/lib/ingenico/direct/sdk/domain/customer_device.rb +51 -0
  77. data/lib/ingenico/direct/sdk/domain/customer_payment_activity.rb +35 -0
  78. data/lib/ingenico/direct/sdk/domain/customer_token.rb +47 -0
  79. data/lib/ingenico/direct/sdk/domain/decrypted_payment_data.rb +43 -0
  80. data/lib/ingenico/direct/sdk/domain/directory_entry.rb +35 -0
  81. data/lib/ingenico/direct/sdk/domain/empty_validator.rb +13 -0
  82. data/lib/ingenico/direct/sdk/domain/error_response.rb +38 -0
  83. data/lib/ingenico/direct/sdk/domain/external_cardholder_authentication_data.rb +59 -0
  84. data/lib/ingenico/direct/sdk/domain/external_token_linked.rb +27 -0
  85. data/lib/ingenico/direct/sdk/domain/fixed_list_validator.rb +33 -0
  86. data/lib/ingenico/direct/sdk/domain/fraud_fields.rb +31 -0
  87. data/lib/ingenico/direct/sdk/domain/fraud_results.rb +27 -0
  88. data/lib/ingenico/direct/sdk/domain/g_pay_three_d_secure.rb +47 -0
  89. data/lib/ingenico/direct/sdk/domain/get_hosted_checkout_response.rb +35 -0
  90. data/lib/ingenico/direct/sdk/domain/get_hosted_tokenization_response.rb +35 -0
  91. data/lib/ingenico/direct/sdk/domain/get_payment_product_groups_response.rb +34 -0
  92. data/lib/ingenico/direct/sdk/domain/get_payment_products_response.rb +34 -0
  93. data/lib/ingenico/direct/sdk/domain/gift_card_purchase.rb +35 -0
  94. data/lib/ingenico/direct/sdk/domain/hosted_checkout_specific_input.rb +55 -0
  95. data/lib/ingenico/direct/sdk/domain/hosted_checkout_specific_output.rb +31 -0
  96. data/lib/ingenico/direct/sdk/domain/label_template_element.rb +31 -0
  97. data/lib/ingenico/direct/sdk/domain/length_validator.rb +31 -0
  98. data/lib/ingenico/direct/sdk/domain/line_item.rb +47 -0
  99. data/lib/ingenico/direct/sdk/domain/line_item_invoice_data.rb +27 -0
  100. data/lib/ingenico/direct/sdk/domain/loan_recipient.rb +43 -0
  101. data/lib/ingenico/direct/sdk/domain/merchant_action.rb +35 -0
  102. data/lib/ingenico/direct/sdk/domain/mobile_payment_data.rb +31 -0
  103. data/lib/ingenico/direct/sdk/domain/mobile_payment_method_specific_input.rb +63 -0
  104. data/lib/ingenico/direct/sdk/domain/mobile_payment_method_specific_output.rb +59 -0
  105. data/lib/ingenico/direct/sdk/domain/mobile_payment_product320_specific_input.rb +31 -0
  106. data/lib/ingenico/direct/sdk/domain/order.rb +71 -0
  107. data/lib/ingenico/direct/sdk/domain/order_line_details.rb +55 -0
  108. data/lib/ingenico/direct/sdk/domain/order_references.rb +31 -0
  109. data/lib/ingenico/direct/sdk/domain/order_status_output.rb +50 -0
  110. data/lib/ingenico/direct/sdk/domain/order_type_information.rb +31 -0
  111. data/lib/ingenico/direct/sdk/domain/payment_account_on_file.rb +31 -0
  112. data/lib/ingenico/direct/sdk/domain/payment_creation_output.rb +39 -0
  113. data/lib/ingenico/direct/sdk/domain/payment_error_response.rb +46 -0
  114. data/lib/ingenico/direct/sdk/domain/payment_output.rb +79 -0
  115. data/lib/ingenico/direct/sdk/domain/payment_product.rb +77 -0
  116. data/lib/ingenico/direct/sdk/domain/payment_product5100_specific_input.rb +27 -0
  117. data/lib/ingenico/direct/sdk/domain/payment_product5402_specific_output.rb +27 -0
  118. data/lib/ingenico/direct/sdk/domain/payment_product5500_specific_output.rb +35 -0
  119. data/lib/ingenico/direct/sdk/domain/payment_product771_specific_output.rb +13 -0
  120. data/lib/ingenico/direct/sdk/domain/payment_product840_customer_account.rb +55 -0
  121. data/lib/ingenico/direct/sdk/domain/payment_product840_specific_output.rb +54 -0
  122. data/lib/ingenico/direct/sdk/domain/payment_product_display_hints.rb +35 -0
  123. data/lib/ingenico/direct/sdk/domain/payment_product_field.rb +47 -0
  124. data/lib/ingenico/direct/sdk/domain/payment_product_field_data_restrictions.rb +35 -0
  125. data/lib/ingenico/direct/sdk/domain/payment_product_field_display_element.rb +39 -0
  126. data/lib/ingenico/direct/sdk/domain/payment_product_field_display_hints.rb +71 -0
  127. data/lib/ingenico/direct/sdk/domain/payment_product_field_form_element.rb +38 -0
  128. data/lib/ingenico/direct/sdk/domain/payment_product_field_tooltip.rb +31 -0
  129. data/lib/ingenico/direct/sdk/domain/payment_product_field_validators.rb +91 -0
  130. data/lib/ingenico/direct/sdk/domain/payment_product_filter.rb +43 -0
  131. data/lib/ingenico/direct/sdk/domain/payment_product_filters_hosted_checkout.rb +38 -0
  132. data/lib/ingenico/direct/sdk/domain/payment_product_group.rb +43 -0
  133. data/lib/ingenico/direct/sdk/domain/payment_product_networks_response.rb +33 -0
  134. data/lib/ingenico/direct/sdk/domain/payment_references.rb +27 -0
  135. data/lib/ingenico/direct/sdk/domain/payment_response.rb +55 -0
  136. data/lib/ingenico/direct/sdk/domain/payment_status_output.rb +58 -0
  137. data/lib/ingenico/direct/sdk/domain/payout_error_response.rb +46 -0
  138. data/lib/ingenico/direct/sdk/domain/payout_output.rb +31 -0
  139. data/lib/ingenico/direct/sdk/domain/payout_response.rb +47 -0
  140. data/lib/ingenico/direct/sdk/domain/payout_result.rb +47 -0
  141. data/lib/ingenico/direct/sdk/domain/payout_status_output.rb +35 -0
  142. data/lib/ingenico/direct/sdk/domain/personal_information.rb +39 -0
  143. data/lib/ingenico/direct/sdk/domain/personal_information_token.rb +31 -0
  144. data/lib/ingenico/direct/sdk/domain/personal_name.rb +35 -0
  145. data/lib/ingenico/direct/sdk/domain/personal_name_token.rb +31 -0
  146. data/lib/ingenico/direct/sdk/domain/product_directory.rb +34 -0
  147. data/lib/ingenico/direct/sdk/domain/protection_eligibility.rb +31 -0
  148. data/lib/ingenico/direct/sdk/domain/range_validator.rb +31 -0
  149. data/lib/ingenico/direct/sdk/domain/redirect_data.rb +31 -0
  150. data/lib/ingenico/direct/sdk/domain/redirect_payment_method_specific_input.rb +67 -0
  151. data/lib/ingenico/direct/sdk/domain/redirect_payment_method_specific_output.rb +67 -0
  152. data/lib/ingenico/direct/sdk/domain/redirect_payment_product809_specific_input.rb +27 -0
  153. data/lib/ingenico/direct/sdk/domain/redirect_payment_product840_specific_input.rb +27 -0
  154. data/lib/ingenico/direct/sdk/domain/redirection_data.rb +27 -0
  155. data/lib/ingenico/direct/sdk/domain/refund_card_method_specific_output.rb +31 -0
  156. data/lib/ingenico/direct/sdk/domain/refund_e_wallet_method_specific_output.rb +39 -0
  157. data/lib/ingenico/direct/sdk/domain/refund_error_response.rb +46 -0
  158. data/lib/ingenico/direct/sdk/domain/refund_mobile_method_specific_output.rb +35 -0
  159. data/lib/ingenico/direct/sdk/domain/refund_output.rb +79 -0
  160. data/lib/ingenico/direct/sdk/domain/refund_payment_product840_customer_account.rb +35 -0
  161. data/lib/ingenico/direct/sdk/domain/refund_payment_product840_specific_output.rb +31 -0
  162. data/lib/ingenico/direct/sdk/domain/refund_redirect_method_specific_output.rb +31 -0
  163. data/lib/ingenico/direct/sdk/domain/refund_request.rb +31 -0
  164. data/lib/ingenico/direct/sdk/domain/refund_response.rb +47 -0
  165. data/lib/ingenico/direct/sdk/domain/refunds_response.rb +34 -0
  166. data/lib/ingenico/direct/sdk/domain/regular_expression_validator.rb +27 -0
  167. data/lib/ingenico/direct/sdk/domain/sepa_direct_debit_payment_method_specific_output.rb +43 -0
  168. data/lib/ingenico/direct/sdk/domain/session_request.rb +33 -0
  169. data/lib/ingenico/direct/sdk/domain/session_response.rb +49 -0
  170. data/lib/ingenico/direct/sdk/domain/shipping.rb +51 -0
  171. data/lib/ingenico/direct/sdk/domain/shopping_cart.rb +65 -0
  172. data/lib/ingenico/direct/sdk/domain/shopping_cart_extension.rb +52 -0
  173. data/lib/ingenico/direct/sdk/domain/test_connection.rb +27 -0
  174. data/lib/ingenico/direct/sdk/domain/three_d_secure.rb +63 -0
  175. data/lib/ingenico/direct/sdk/domain/three_d_secure_base.rb +47 -0
  176. data/lib/ingenico/direct/sdk/domain/three_d_secure_data.rb +35 -0
  177. data/lib/ingenico/direct/sdk/domain/three_d_secure_results.rb +31 -0
  178. data/lib/ingenico/direct/sdk/domain/token_card.rb +35 -0
  179. data/lib/ingenico/direct/sdk/domain/token_card_data.rb +31 -0
  180. data/lib/ingenico/direct/sdk/domain/token_card_specific_input.rb +31 -0
  181. data/lib/ingenico/direct/sdk/domain/token_data.rb +31 -0
  182. data/lib/ingenico/direct/sdk/domain/token_e_wallet.rb +35 -0
  183. data/lib/ingenico/direct/sdk/domain/token_response.rb +55 -0
  184. data/lib/ingenico/direct/sdk/domain/value_mapping_element.rb +38 -0
  185. data/lib/ingenico/direct/sdk/endpoint_configuration.rb +127 -0
  186. data/lib/ingenico/direct/sdk/exceptions.rb +8 -0
  187. data/lib/ingenico/direct/sdk/factory.rb +136 -0
  188. data/lib/ingenico/direct/sdk/idempotence_exception.rb +24 -0
  189. data/lib/ingenico/direct/sdk/logging.rb +10 -0
  190. data/lib/ingenico/direct/sdk/logging/communicator_logger.rb +22 -0
  191. data/lib/ingenico/direct/sdk/logging/log_message_builder.rb +56 -0
  192. data/lib/ingenico/direct/sdk/logging/logging_capable.rb +19 -0
  193. data/lib/ingenico/direct/sdk/logging/logging_util.rb +271 -0
  194. data/lib/ingenico/direct/sdk/logging/request_log_message_builder.rb +39 -0
  195. data/lib/ingenico/direct/sdk/logging/response_log_message_builder.rb +34 -0
  196. data/lib/ingenico/direct/sdk/logging/ruby_communicator_logger.rb +57 -0
  197. data/lib/ingenico/direct/sdk/logging/stdout_communicator_logger.rb +34 -0
  198. data/lib/ingenico/direct/sdk/marshaller.rb +24 -0
  199. data/lib/ingenico/direct/sdk/marshaller_syntax_exception.rb +6 -0
  200. data/lib/ingenico/direct/sdk/merchant/hostedcheckout/hosted_checkout_client.rb +87 -0
  201. data/lib/ingenico/direct/sdk/merchant/hostedtokenization/hosted_tokenization_client.rb +87 -0
  202. data/lib/ingenico/direct/sdk/merchant/merchant_client.rb +83 -0
  203. data/lib/ingenico/direct/sdk/merchant/payments/payments_client.rb +291 -0
  204. data/lib/ingenico/direct/sdk/merchant/payouts/payouts_client.rb +87 -0
  205. data/lib/ingenico/direct/sdk/merchant/productgroups/get_product_group_params.rb +58 -0
  206. data/lib/ingenico/direct/sdk/merchant/productgroups/get_product_groups_params.rb +58 -0
  207. data/lib/ingenico/direct/sdk/merchant/productgroups/product_groups_client.rb +88 -0
  208. data/lib/ingenico/direct/sdk/merchant/products/get_payment_product_networks_params.rb +39 -0
  209. data/lib/ingenico/direct/sdk/merchant/products/get_payment_product_params.rb +58 -0
  210. data/lib/ingenico/direct/sdk/merchant/products/get_payment_products_params.rb +58 -0
  211. data/lib/ingenico/direct/sdk/merchant/products/get_product_directory_params.rb +31 -0
  212. data/lib/ingenico/direct/sdk/merchant/products/products_client.rb +156 -0
  213. data/lib/ingenico/direct/sdk/merchant/services/services_client.rb +52 -0
  214. data/lib/ingenico/direct/sdk/merchant/sessions/sessions_client.rb +55 -0
  215. data/lib/ingenico/direct/sdk/merchant/tokens/tokens_client.rb +117 -0
  216. data/lib/ingenico/direct/sdk/meta_data_provider.rb +150 -0
  217. data/lib/ingenico/direct/sdk/modules.rb +71 -0
  218. data/lib/ingenico/direct/sdk/not_found_exception.rb +16 -0
  219. data/lib/ingenico/direct/sdk/param_request.rb +11 -0
  220. data/lib/ingenico/direct/sdk/pooled_connection.rb +21 -0
  221. data/lib/ingenico/direct/sdk/proxy_configuration.rb +74 -0
  222. data/lib/ingenico/direct/sdk/reference_exception.rb +14 -0
  223. data/lib/ingenico/direct/sdk/request_header.rb +50 -0
  224. data/lib/ingenico/direct/sdk/request_param.rb +23 -0
  225. data/lib/ingenico/direct/sdk/response_exception.rb +47 -0
  226. data/lib/ingenico/direct/sdk/response_header.rb +42 -0
  227. data/lib/ingenico/direct/sdk/validation_exception.rb +14 -0
  228. data/lib/ingenico/direct/sdk/webhooks.rb +11 -0
  229. data/lib/ingenico/direct/sdk/webhooks/api_version_mismatch_exception.rb +20 -0
  230. data/lib/ingenico/direct/sdk/webhooks/in_memory_secret_key_store.rb +56 -0
  231. data/lib/ingenico/direct/sdk/webhooks/secret_key_not_available_exception.rb +17 -0
  232. data/lib/ingenico/direct/sdk/webhooks/secret_key_store.rb +16 -0
  233. data/lib/ingenico/direct/sdk/webhooks/signature_validation_exception.rb +19 -0
  234. data/lib/ingenico/direct/sdk/webhooks/webhooks.rb +22 -0
  235. data/lib/ingenico/direct/sdk/webhooks/webhooks_event.rb +58 -0
  236. data/lib/ingenico/direct/sdk/webhooks/webhooks_helper.rb +99 -0
  237. data/lib/ingenico/direct/sdk/webhooks/webhooks_helper_builder.rb +25 -0
  238. metadata +385 -0
@@ -0,0 +1,8 @@
1
+ prefix = 'ingenico/direct/sdk/'
2
+ suffix = '_exception'
3
+ exception_types = %w[api authorization communication declined_transaction
4
+ declined_payment declined_refund
5
+ direct idempotence marshaller_syntax not_found
6
+ reference response validation]
7
+
8
+ exception_types.each { |type| require prefix + type + suffix }
@@ -0,0 +1,136 @@
1
+ require 'yaml'
2
+
3
+ module Ingenico::Direct::SDK
4
+
5
+ # Convenience class that constructs instances of several other classes in the SDK.
6
+ # Provides methods to construct
7
+ # {Ingenico::Direct::SDK::CommunicatorConfiguration}, {Ingenico::Direct::SDK::Communicator} and {Ingenico::Direct::SDK::Client} instances.
8
+ class Factory
9
+
10
+ # Creates and returns a {Ingenico::Direct::SDK::CommunicatorConfiguration} based on the configuration in the file located at _configuration_file_name_.
11
+ #
12
+ # @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
13
+ # @param api_key_id [String] Key id for the GlobalCollect service.
14
+ # @param secret_api_key [String] Secret key used for authentication to the GlobalCollect service.
15
+ # @return [Ingenico::Direct::SDK::CommunicatorConfiguration] The created communicator configuration
16
+ def self.create_configuration(config_file_name, api_key_id, secret_api_key)
17
+ properties = YAML::load_file(config_file_name)
18
+ CommunicatorConfiguration.new(properties: properties,
19
+ api_key_id: api_key_id,
20
+ secret_api_key: secret_api_key)
21
+ end
22
+
23
+ # Creates and returns an {Ingenico::Direct::SDK::Communicator} that can be used for communication with the GlobalCollect service.
24
+ #
25
+ # @param configuration [Ingenico::Direct::SDK::CommunicatorConfiguration] contains configuration settings to be used by the client.
26
+ # @param meta_data_provider [Ingenico::Direct::SDK::MetaDataProvider,nil] stores the metadata for the communicating client.
27
+ # @param connection [Ingenico::Direct::SDK::Connection,nil] connection that can be used to communicate with the Ingenico Direct platform.
28
+ # @param authenticator [Ingenico::Direct::SDK::Authenticator,nil] authenticator that can authenticate messages sent to the Ingenico Direct platform.
29
+ # @param marshaller [Ingenico::Direct::SDK::Marshaller,nil] marshaller that marshalls and unmarshalls messages sent to the Ingenico Direct platform.
30
+ # @return [Ingenico::Direct::SDK::Communicator] The created communicator
31
+ def self.create_communicator_from_configuration(configuration, meta_data_provider: nil, connection: nil, authenticator: nil, marshaller: DefaultImpl::DefaultMarshaller.INSTANCE)
32
+ meta_data_provider ||= MetaDataProvider.new(configuration.integrator, shopping_cart_extension: configuration.shopping_cart_extension)
33
+ connection ||= DefaultImpl::DefaultConnection.new({ connect_timeout: configuration.connect_timeout,
34
+ socket_timeout: configuration.socket_timeout,
35
+ max_connections: configuration.max_connections,
36
+ proxy_configuration: configuration.proxy_configuration })
37
+ authenticator ||= DefaultImpl::DefaultAuthenticator.new(configuration.api_key_id,
38
+ configuration.secret_api_key,
39
+ configuration.authorization_type)
40
+ Communicator.new(configuration.api_endpoint, connection, authenticator, meta_data_provider, marshaller)
41
+ end
42
+
43
+ # Creates and returns an {Ingenico::Direct::SDK::Communicator} that is used for communication with the GlobalCollect service.
44
+ #
45
+ # @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
46
+ # @param api_key_id [String] Key id for the GlobalCollect service.
47
+ # @param secret_api_key [String] Secret key used for authentication to the GlobalCollect service.
48
+ # @param meta_data_provider [Ingenico::Direct::SDK::MetaDataProvider,nil] stores the metadata for the communicating client.
49
+ # @param connection [Ingenico::Direct::SDK::Connection,nil] connection that can be used to communicate with the Ingenico Direct platform.
50
+ # @param authenticator [Ingenico::Direct::SDK::Authenticator,nil] authenticator that can authenticate messages sent to the Ingenico Direct platform.
51
+ # @return [Ingenico::Direct::SDK::Communicator] The created communicator
52
+ def self.create_communicator_from_file(config_file_name, api_key_id, secret_api_key,
53
+ meta_data_provider: nil, connection: nil, authenticator: nil,
54
+ marshaller: DefaultImpl::DefaultMarshaller.INSTANCE)
55
+ configuration = create_configuration(config_file_name, api_key_id, secret_api_key)
56
+ create_communicator_from_configuration(configuration, meta_data_provider: meta_data_provider, connection: connection,
57
+ authenticator: authenticator, marshaller: marshaller)
58
+ end
59
+
60
+ # Creates and returns an {Ingenico::Direct::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
61
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
62
+ #
63
+ # @example Providing a code block
64
+ # Factory.create_client_from_configuration(configuration) do |client|
65
+ # client.merchant(merchant_id).services.testconnection
66
+ # end
67
+ # # client is closed here
68
+ #
69
+ # @param configuration [Ingenico::Direct::SDK::CommunicatorConfiguration] contains configuration settings to be used by the client.
70
+ # @return [Ingenico::Direct::SDK::Client] The created client
71
+ def self.create_client_from_configuration(configuration)
72
+ communicator = create_communicator_from_configuration(configuration)
73
+ client = Client.new(communicator)
74
+ if block_given?
75
+ begin
76
+ yield client
77
+ ensure
78
+ client.close
79
+ end
80
+ else
81
+ return client
82
+ end
83
+ end
84
+
85
+ # Creates and returns an {Ingenico::Direct::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
86
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
87
+ #
88
+ # @example Providing a code block
89
+ # Factory.create_client_from_communicator(communicator) do |client|
90
+ # client.merchant(merchant_id).services.testconnection
91
+ # end
92
+ # # client is closed here
93
+ #
94
+ # @param communicator [Ingenico::Direct::SDK::Communicator] provides network communication service for the Client
95
+ # @return [Ingenico::Direct::SDK::Client] The created client
96
+ def self.create_client_from_communicator(communicator)
97
+ client = Client.new(communicator)
98
+ if block_given?
99
+ begin
100
+ yield client
101
+ ensure
102
+ client.close
103
+ end
104
+ else
105
+ return client
106
+ end
107
+ end
108
+
109
+ # Creates and returns an {Ingenico::Direct::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
110
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
111
+ #
112
+ # @example Providing a code block
113
+ # Factory.create_client_from_file(config_file_name, api_key_id, secret_api_key) do |client|
114
+ # client.merchant(merchant_id).services.testconnection
115
+ # end
116
+ # # client is closed here
117
+ #
118
+ # @param config_file_name [String] Path to the configuration file to use, should be in YAML format.
119
+ # @param api_key_id [String] Key id for the GlobalCollect service.
120
+ # @param secret_api_key [String] Secret key used for authentication to the GlobalCollect service.
121
+ # @return [Ingenico::Direct::SDK::Client] The created client
122
+ def self.create_client_from_file(config_file_name, api_key_id, secret_api_key)
123
+ communicator = create_communicator_from_file(config_file_name, api_key_id, secret_api_key)
124
+ client = Client.new(communicator)
125
+ if block_given?
126
+ begin
127
+ yield client
128
+ ensure
129
+ client.close
130
+ end
131
+ else
132
+ return client
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,24 @@
1
+ module Ingenico::Direct::SDK
2
+
3
+ # This exception is thrown when a response from the Ingenico ePayments platform indicates
4
+ # a request with the same _idempotence_key_ was received earlier.
5
+ # The _idempotence_request_timestamp_ indicates the time when the first request with this _idempotence_key_ arrived.
6
+ #
7
+ # @attr_reader [String] idempotence_key The idempotence key used in the request.
8
+ # @attr_reader [Integer] idempotence_request_timestamp A timestamp indicating the arrival time of the request that conflicts with the request just sent.
9
+ class IdempotenceException < ApiException
10
+
11
+ # Create a new IdempotenceException
12
+ # @see ApiException#initialize
13
+ def initialize(status_code, response_body, error_id, errors, idempotence_key,
14
+ idempotence_request_timestamp,
15
+ message='the Ingenico ePayments platform returned a duplicate request error response')
16
+ super(status_code, response_body, error_id, errors, message)
17
+ @idempotence_key = idempotence_key
18
+ @idempotence_request_timestamp = idempotence_request_timestamp
19
+ end
20
+
21
+ attr_reader :idempotence_key
22
+ attr_reader :idempotence_request_timestamp
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ prefix = 'ingenico/direct/sdk/logging'
2
+
3
+ require "#{prefix}/logging_capable"
4
+ require "#{prefix}/log_message_builder"
5
+ require "#{prefix}/request_log_message_builder"
6
+ require "#{prefix}/response_log_message_builder"
7
+ require "#{prefix}/logging_util"
8
+ require "#{prefix}/communicator_logger"
9
+ require "#{prefix}/ruby_communicator_logger"
10
+ require "#{prefix}/stdout_communicator_logger"
@@ -0,0 +1,22 @@
1
+ module Ingenico::Direct::SDK
2
+ module Logging
3
+
4
+ # Base logger class used in this SDK. This class is an interface and cannot be instantiated.
5
+ class CommunicatorLogger
6
+ # Interface, no instantiation
7
+ # @see Ingenico::Direct::SDK::Logging::StdoutCommunicatorLogger
8
+ # @see Ingenico::Direct::SDK::Logging::RubyCommunicatorLogger
9
+ def initialize
10
+ raise NotImplementedError, "#{self.class.name} is not implemented."
11
+ end
12
+
13
+ # Logs a message with or without exception
14
+ #
15
+ # @param message [String] the message to log
16
+ # @param thrown [Exception, false] the exception to log, or false to log no exception
17
+ def log(message, thrown = false)
18
+ raise NotImplementedError, "#{self.class.name}#log() is not implemented."
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,56 @@
1
+ module Ingenico::Direct::SDK
2
+ module Logging
3
+
4
+ # Abstract class used to construct a message describing a request or response.
5
+ #
6
+ # @attr_reader [String] request_id An identifier assigned to the request and response
7
+ # @attr_reader [String] headers Request or response headers in string form
8
+ # @attr_reader [String] body Request or response body as a string
9
+ # @attr_reader [String] content_type Content type of the body, generally 'application/json' or 'text/html'
10
+ class LogMessageBuilder
11
+
12
+ attr_reader :request_id
13
+ attr_reader :headers
14
+ attr_reader :body
15
+ attr_reader :content_type
16
+
17
+ # Create a new LogMessageBuilder
18
+ def initialize(request_id)
19
+ raise ArgumentError if request_id.nil? || request_id.empty?
20
+ @request_id = request_id
21
+ @headers = ''
22
+ end
23
+
24
+ # Adds a single header to the #headers string
25
+ def add_headers(name, value)
26
+ @headers += ', ' unless @headers.empty?
27
+ @headers += "#{name}='#{LoggingUtil.obfuscate_header(name, value)}'"
28
+ end
29
+
30
+ # Sets the body of this message to the parameter body.
31
+
32
+ # @param body [String] the message body
33
+ # @param content_type [String] the content type of the body
34
+ def set_body(body, content_type)
35
+ @body = LoggingUtil.obfuscate_body(body)
36
+ @content_type = content_type
37
+ end
38
+
39
+ # Constructs and returns the log message as a string.
40
+ def get_message
41
+ raise NotImplementedError, "#{self.class.name}#get_message() is not implemented."
42
+ end
43
+
44
+ def to_s
45
+ self.class == LogMessageBuilder ?
46
+ super.to_s :
47
+ get_message
48
+ end
49
+
50
+ # Returns an empty string if the parameter is nil, and returns the parameter itself otherwise
51
+ protected def empty_if_null(value)
52
+ value.nil? ? '' : value
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,19 @@
1
+ module Ingenico
2
+ module Direct
3
+ module SDK
4
+ module Logging
5
+
6
+ # Abstract mixin module that allows loggers to be registered to an object.
7
+ module LoggingCapable
8
+ def enable_logging(communicator_logger)
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def disable_logging
13
+ raise NotImplementedError
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,271 @@
1
+ module Ingenico::Direct::SDK
2
+ module Logging
3
+
4
+ # Class responsible for obfuscating sensitive data in a message body.
5
+ class ValueObfuscator
6
+
7
+ class << self
8
+
9
+ alias_method :private_new, :new
10
+
11
+ protected :private_new, :new
12
+ end
13
+
14
+ public
15
+
16
+ def self.INSTANCE
17
+ # use lazy instantiation
18
+ @@INSTANCE ||= ValueObfuscator.new
19
+ end
20
+
21
+ # Obfuscates the parameter value.
22
+ def obfuscate_value(value)
23
+ (value.nil? or value.empty?) ? value : "*#{value.length}"
24
+ end
25
+ end # end of ValueObfuscator
26
+
27
+ # Class responsible for obfuscating sensitive data.
28
+ class SensitiveValueObfuscator
29
+
30
+ class << self
31
+
32
+ alias_method :private_new, :new
33
+
34
+ protected :private_new, :new
35
+ end
36
+ public
37
+
38
+ def self.INSTANCE
39
+ # use lazy instantiation
40
+ @@INSTANCE ||= SensitiveValueObfuscator.new
41
+ end
42
+
43
+ # @return an arbitrary number of '*', or null/empty if the value is null/empty.
44
+ def obfuscate_value(value)
45
+ value.nil? or value.empty? ? value : "***"
46
+ end
47
+ end # end of SensitiveValueObfuscator
48
+
49
+ class Obfuscator
50
+ def initialize(obfuscators, case_insensitive)
51
+ raise ArgumentError unless obfuscators.is_a? Hash
52
+ @obfuscators = copy(obfuscators, case_insensitive)
53
+ end
54
+
55
+ private
56
+
57
+ # case insensitive hash
58
+ # @private
59
+ class HashClod < Hash
60
+
61
+ def initialize(other)
62
+ other.each { |k, v| self.[]=(k, v) }
63
+ end
64
+
65
+ def [](key)
66
+ super _insensitive(key)
67
+ end
68
+
69
+ def []=(key, value)
70
+ super _insensitive(key), value
71
+ end
72
+
73
+ protected
74
+
75
+ def _insensitive(key)
76
+ key.respond_to?(:upcase) ? key.upcase : key
77
+ end
78
+ end # end of HashClod
79
+
80
+ def copy(obfuscators, case_insensitive)
81
+ cp = case_insensitive ? HashClod.new(obfuscators) : obfuscators
82
+ Marshal.load(Marshal.dump(cp)) # deep copy
83
+ end
84
+
85
+ public
86
+
87
+ def obfuscate_value(key, value)
88
+ obfuscator = @obfuscators[key]
89
+ if obfuscator.nil?
90
+ value
91
+ else
92
+ obfuscator.obfuscate_value(value)
93
+ end
94
+ end
95
+
96
+ # A convenient wrapper to build obfuscators
97
+ class Builder
98
+ attr_accessor :obfuscators
99
+
100
+ def initialize
101
+ raise NotImplementedError, "#{self.class.name} is not implemented."
102
+ end
103
+
104
+ def with_field(key)
105
+ @obfuscators[key] = ValueObfuscator.INSTANCE
106
+ self
107
+ end
108
+
109
+ def with_sensitive_field(key)
110
+ @obfuscators[key] = SensitiveValueObfuscator.INSTANCE
111
+ self
112
+ end
113
+
114
+ def build
115
+ raise NotImplementedError, "#{self.class.name}#build() is not implemented."
116
+ end
117
+ end # Builder
118
+ end # Obfuscator
119
+
120
+ # Class that obfuscates headers of a message
121
+ class HeaderObfuscator < Obfuscator
122
+ def initialize(obfuscators)
123
+ # case insensitive
124
+ super(obfuscators, true)
125
+ end
126
+
127
+ def self.builder
128
+ Builder.new
129
+ end
130
+
131
+ class Builder < Obfuscator::Builder
132
+ def initialize
133
+ @obfuscators = {}
134
+ end
135
+
136
+ def with_field(name)
137
+ raise ArgumentError unless name.is_a? String
138
+ super(name)
139
+ end
140
+
141
+ def with_sensitive_field(name)
142
+ raise ArgumentError unless name.is_a? String
143
+ super(name)
144
+ end
145
+
146
+ def build
147
+ HeaderObfuscator.new(obfuscators)
148
+ end
149
+ end
150
+ end # end of HeadObfuscator
151
+
152
+ # Class that obfuscates properties in the JSON body of a message
153
+ class PropertyObfuscator < Obfuscator
154
+ def initialize(obfuscators)
155
+ # case sensitive
156
+ super(obfuscators, false)
157
+ @property_pattern = build_property_pattern(obfuscators.keys)
158
+ end
159
+
160
+ private
161
+
162
+ def build_property_pattern(pn)
163
+ return /$^/ if pn.empty? # no possible match
164
+ # Regex to create:
165
+ # (["'])(X|Y|Z)\1\s*:\s*(?:(["'])(.*?)(?<!\\)\3|([^"'\s\[\{]\S*))
166
+ # Groups:
167
+ # 1: opening " or ' for the property name
168
+ # 2: property name
169
+ # 3: opening " or ' for the value
170
+ # 4: quoted value
171
+ # 5: non-quoted-value
172
+ # The negative lookbehind is to allow escaped quotes to be part of
173
+ # the value. What this does not allow currently is having values end
174
+ # with a \ (which would be escaped to \\).
175
+ regex = pn.inject("([\"'])(") { |r, p| "#{r}#{Regexp.quote(p)}|"}.chop <<
176
+ ")\\1\\s*:\\s*(?:([\"'])(.*?)(?<!\\\\)\\3|([^\"'\\s\\[\\{]((?!,)\\S)*))"
177
+ /#{regex}/m # dotall mode
178
+ end
179
+
180
+ public
181
+
182
+ def obfuscate(body)
183
+ return nil if body.nil?
184
+ return "" if body.empty?
185
+
186
+ body.gsub(@property_pattern) do
187
+ m = Regexp.last_match
188
+ property_name = m[2]
189
+ value = m[4] || m[5]
190
+ # copy value 'cause it's part of m[0]
191
+ m[0].sub(value, obfuscate_value(property_name, value.dup))
192
+ end
193
+ end
194
+
195
+ def self.builder
196
+ Builder.new
197
+ end
198
+
199
+ class Builder < Obfuscator::Builder
200
+ def initialize
201
+ @obfuscators = {}
202
+ end
203
+
204
+ def with_field(property)
205
+ raise ArgumentError unless property.is_a? String
206
+ super(property)
207
+ end
208
+
209
+ def with_sensitive_field(property)
210
+ raise ArgumentError unless property.is_a? String
211
+ super(property)
212
+ end
213
+
214
+ def build
215
+ PropertyObfuscator.new(obfuscators)
216
+ end
217
+ end
218
+ end # end of property obfuscator
219
+
220
+ module LoggingUtil
221
+ @@PROPERTY_OBFUSCATOR = PropertyObfuscator.builder
222
+ .with_field("cardNumber")
223
+ .with_field("expiryDate")
224
+ .with_field("cvv")
225
+ .with_field("iban")
226
+ .with_field("accountNumber")
227
+ .with_field("reformattedAccountNumber")
228
+ .with_field("additionalInfo")
229
+ .with_field("cardholderName")
230
+ .with_field("dateOfBirth")
231
+ .with_field("emailAddress")
232
+ .with_field("faxNumber")
233
+ .with_field("firstName")
234
+ .with_field("houseNumber")
235
+ .with_field("mobilePhoneNumber")
236
+ .with_field("passengerName")
237
+ .with_field("phoneNumber")
238
+ .with_field("street")
239
+ .with_field("surname")
240
+ .with_field("workPhoneNumber")
241
+ .with_field("zip")
242
+ .with_field("bin")
243
+ .with_field("value")
244
+ .with_sensitive_field("keyId")
245
+ .with_sensitive_field("secretKey")
246
+ .with_sensitive_field("publicKey")
247
+ .with_sensitive_field("userAuthenticationToken")
248
+ .with_sensitive_field("encryptedPayload")
249
+ .with_sensitive_field("decryptedPayload")
250
+ .with_sensitive_field("encryptedCustomerInput")
251
+ .build
252
+
253
+ @@HEADER_OBFUSCATOR = HeaderObfuscator.builder
254
+ .with_sensitive_field("Authorization")
255
+ .with_sensitive_field("WWW-Authenticate")
256
+ .with_sensitive_field("Proxy-Authenticate")
257
+ .with_sensitive_field("Proxy-Authorization")
258
+ .with_sensitive_field("X-GCS-Authentication-Token")
259
+ .with_sensitive_field("X-GCS-CallerPassword")
260
+ .build
261
+
262
+ def self.obfuscate_body(body)
263
+ @@PROPERTY_OBFUSCATOR.obfuscate(body)
264
+ end
265
+
266
+ def self.obfuscate_header(name, value)
267
+ @@HEADER_OBFUSCATOR.obfuscate_value(name, value)
268
+ end
269
+ end # end of LoggingUtil
270
+ end
271
+ end