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,13 @@
1
+ module Ingenico::Direct::SDK
2
+
3
+ # This exception is thrown when a request sent to the Ingenico ePayments platform is not correctly authenticated.
4
+ # Corresponds to a HTTP status code of 403.
5
+ # @see ApiException#initialize
6
+ class AuthorizationException < ApiException
7
+
8
+ def initialize(status_code, response_body, error_id, errors,
9
+ message = 'the Ingenico ePayments platform returned an authorization error response')
10
+ super(status_code, response_body, error_id, errors, message)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Ingenico::Direct::SDK
2
+
3
+ # A CallContext is used to identify requests and manage idempotent requests.
4
+ # A CallContext contains the following:
5
+ #
6
+ # idempotence_key:: A randomly generated key used to identify requests
7
+ # idempotence_request_timestamp:: If a previous request arrived with the same idempotence key,
8
+ # this value will be set to a timestamp of that request.
9
+ #
10
+ # @attr_reader [String] idempotence_key The idempotence key used to identify this request.
11
+ # If two requests share the same _idempotence_key_, they are considered to be the same request
12
+ # and only the first request will be processed.
13
+ # @attr [Integer] idempotence_request_timestamp If two or more requests arrive at the Ingenico ePayments platform with the same _idempotence_key_,
14
+ # the _idempotence_request_timestamp_ will be set to the arrival time of the first of these requests.
15
+ class CallContext
16
+ @idempotence_request_timestamp = nil
17
+ @idempotence_key = nil
18
+
19
+ def initialize(idempotence_key = nil)
20
+ @idempotence_key = idempotence_key
21
+ end
22
+
23
+ attr_reader :idempotence_key
24
+ attr_accessor :idempotence_request_timestamp
25
+ end
26
+ end
@@ -0,0 +1,85 @@
1
+ #
2
+ # This class was auto-generated from the API references found at
3
+ # https://support.direct.ingenico.com/documentation/api/reference/
4
+ #
5
+ require 'ingenico/direct/sdk/api_resource'
6
+ require 'ingenico/direct/sdk/data_object'
7
+ require 'ingenico/direct/sdk/logging/logging_capable'
8
+ require 'ingenico/direct/sdk/merchant/merchant_client'
9
+ require 'base64'
10
+
11
+ module Ingenico
12
+ module Direct
13
+ module SDK
14
+ # Ingenico ePayments platform client.
15
+ #
16
+ # This client and all its child clients are bound to one specific value for the X-GCS-ClientMetaInfo header.
17
+ #
18
+ # To get a new client with a different header value, use with_client_meta_info.
19
+ #
20
+ # Thread safe.
21
+ class Client < ApiResource
22
+ include Logging::LoggingCapable
23
+
24
+ # @return [String]
25
+ def self.API_VERSION
26
+ 'v2'
27
+ end
28
+
29
+ # @param communicator [Ingenico::Direct::SDK::Communicator]
30
+ # @param client_meta_info [String, nil]
31
+ def initialize(communicator, client_meta_info = nil)
32
+ super(communicator, nil, client_meta_info)
33
+ end
34
+
35
+ # @param client_meta_info [String, nil] JSON string containing the meta data for the client
36
+ # @return [Ingenico::Direct::SDK::Client] a Client which uses the passed meta data for the X-GCS-ClientMetaInfo header.
37
+ # @raise [Ingenico::Direct::SDK::MarshallerSyntaxException] if the given clientMetaInfo is not a valid JSON string
38
+ def with_client_meta_info(client_meta_info)
39
+ if client_meta_info
40
+ # Checking to see if this is valid JSON (no JSON parse exceptions)
41
+ @communicator.marshaller.unmarshal(client_meta_info, DataObject)
42
+ client_meta_info = Base64.strict_encode64(client_meta_info)
43
+ return @client_meta_info == client_meta_info ? self : Client.new(@communicator, client_meta_info)
44
+ end
45
+ @client_meta_info ? Client.new(@communicator) : self
46
+ end
47
+
48
+ # Utility method that delegates the call to this client's communicator.
49
+ def close_idle_connections(idle_time)
50
+ @communicator.close_idle_connections(idle_time)
51
+ end
52
+
53
+ # Utility method that delegates the call to this client's communicator.
54
+ def close_expired_connections
55
+ @communicator.close_expired_connections
56
+ end
57
+
58
+ # Turns on logging using the given communicator logger.
59
+ # @param communicator_logger [Ingenico::Direct::SDK::Logging::CommunicatorLogger]
60
+ def enable_logging(communicator_logger)
61
+ @communicator.enable_logging(communicator_logger)
62
+ end
63
+
64
+ # Turns off logging.
65
+ def disable_logging
66
+ @communicator.disable_logging
67
+ end
68
+
69
+ # Releases any system resources associated with this object.
70
+ def close
71
+ @communicator.close
72
+ end
73
+
74
+ # Resource /v2/!{merchantId}
75
+ # @param merchant_id [String]
76
+ # @return [Ingenico::Direct::SDK::Merchant::MerchantClient]
77
+ def merchant(merchant_id)
78
+ Ingenico::Direct::SDK::Merchant::MerchantClient.new(self, {
79
+ 'merchantId'.freeze => merchant_id
80
+ })
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,16 @@
1
+ module Ingenico::Direct::SDK
2
+
3
+ # This exception is used when an error occurs during network communication with the Ingenico ePayments platform.
4
+ # A common cause is a timeout while connecting or when receiving or sending data.
5
+ #
6
+ # @attr [Exception] cause The error that is the cause of this error.
7
+ class CommunicationException < RuntimeError
8
+
9
+ def initialize(cause)
10
+ super()
11
+ @cause = cause
12
+ end
13
+
14
+ attr_accessor :cause
15
+ end
16
+ end
@@ -0,0 +1,301 @@
1
+ require 'uri'
2
+
3
+ module Ingenico::Direct::SDK
4
+ # Class responsible for facilitating communication with the Ingenico ePayments platform.
5
+ # It combines the following classes to provide communication functionality:
6
+ #
7
+ # api_endpoint:: The base URI ({URI::HTTP}) to the Ingenico ePayments platform
8
+ # connection:: {Ingenico::Direct::SDK::Connection} used to communicate with the Ingenico ePayments platform
9
+ # authenticator:: {Ingenico::Direct::SDK::Authenticator} used for authenticating messages sent
10
+ # meta_data_provider:: {Ingenico::Direct::SDK::MetaDataProvider} object containing information relevant for sending requests
11
+ # marshaller:: {Ingenico::Direct::SDK::Marshaller} that is used to marshal and unmarshal data to and from JSON format
12
+ #
13
+ # @attr_reader [Ingenico::Direct::SDK::Marshaller] marshaller A Marshaller instance used by the communicator for serializing/deserializing to/from JSON
14
+ #
15
+ class Communicator
16
+ include Logging::LoggingCapable
17
+
18
+ # Creates a new Communicator based on the given arguments.
19
+ #
20
+ # @param api_endpoint [String] the base URL to the Ingenico ePayments platform
21
+ # @param connection [Ingenico::Direct::SDK::Connection] used to communicate with the Ingenico ePayments platform
22
+ # @param authenticator [Ingenico::Direct::SDK::Authenticator] used for authenticating messages sent
23
+ # @param meta_data_provider [Ingenico::Direct::SDK::MetaDataProvider] object containing information relevant for sending requests
24
+ # @param marshaller [Ingenico::Direct::SDK::Marshaller] used to marshal and unmarshal data to and from JSON format
25
+ #
26
+ def initialize(api_endpoint, connection, authenticator, meta_data_provider, marshaller)
27
+ raise ArgumentError, 'api_endpoint is required' unless api_endpoint
28
+ raise ArgumentError, 'connection is required' unless connection
29
+ raise ArgumentError, 'authenticator is required' unless authenticator
30
+ raise ArgumentError, 'meta_data_provider is required' unless meta_data_provider
31
+ raise ArgumentError('marshaller is required') unless marshaller
32
+
33
+ @api_endpoint = URI(api_endpoint)
34
+ if @api_endpoint.path.length.positive? || @api_endpoint.query || @api_endpoint.fragment
35
+ raise ArgumentError, "Base URL should not contain a path, query or fragment #{@api_endpoint}"
36
+ end
37
+ @connection = connection
38
+ @authenticator = authenticator
39
+ @meta_data_provider = meta_data_provider
40
+ @marshaller = marshaller
41
+ end
42
+
43
+ # Performs a GET request to the Ingenico ePayments platform and returns the response as the given response type.
44
+ #
45
+ # @param relative_path [String] path relative to the API endpoint
46
+ # @param request_headers [Array<Ingenico::Direct::SDK::RequestHeader>, nil] optional array of request headers
47
+ # @param request_parameters [Ingenico::Direct::SDK::ParamRequest, nil] optional request parameters
48
+ # @param response_type [Type] the response type.
49
+ # @param context [Ingenico::Direct::SDK::CallContext, nil] optional call context.
50
+ # @return the response of the GET request as the given response type
51
+ # @raise [Ingenico::Direct::SDK::ResponseException] if the request could not be fulfilled successfully.
52
+ # This occurs for example if the request is not authenticated correctly
53
+ # @raise [Ingenico::Direct::SDK::NotFoundException] if the requested resource is not found
54
+ # @raise [Ingenico::Direct::SDK::CommunicationException] if there is an error in communicating with the Ingenico ePayments platform.
55
+ # This occurs for example if a timeout occurs.
56
+ def get(relative_path, request_headers, request_parameters, response_type, context)
57
+ connection = @connection
58
+ request_parameter_list = request_parameters&.to_request_parameters
59
+ uri = to_absolute_uri(relative_path, request_parameter_list)
60
+
61
+ request_headers ||= []
62
+ add_generic_headers('GET', uri, request_headers, context)
63
+
64
+ response_status_code, response_headers, response_body = nil
65
+ connection.get(uri, request_headers) do |status_code, headers, content|
66
+ response_status_code = status_code
67
+ response_headers = headers
68
+ response_body = content.read.force_encoding('UTF-8')
69
+ end
70
+ process_response(response_body, response_status_code, response_headers, response_type, relative_path, context)
71
+ end
72
+
73
+ # Performs a DELETE request to the Ingenico ePayments platform and returns the response as the given response type.
74
+ #
75
+ # @param relative_path [String] Path relative to the API endpoint
76
+ # @param request_headers [Array<Ingenico::Direct::SDK::RequestHeader>, nil] Optional array of request headers
77
+ # @param request_parameters [Ingenico::Direct::SDK::ParamRequest, nil] Optional request parameters
78
+ # @param response_type [Type] The response type.
79
+ # @param context [Ingenico::Direct::SDK::CallContext, nil] Optional call context.
80
+ # @return The response of the DELETE request as the given response type
81
+ # @raise [Ingenico::Direct::SDK::ResponseException] if the request could not be fulfilled successfully.
82
+ # This occurs for example if the request is not authenticated correctly
83
+ # @raise [Ingenico::Direct::SDK::NotFoundException] if the requested resource is not found
84
+ # @raise [Ingenico::Direct::SDK::CommunicationException] if there is an error in communicating with the Ingenico ePayments platform.
85
+ # This occurs for example if a timeout occurs.
86
+ def delete(relative_path, request_headers, request_parameters, response_type, context)
87
+ connection = @connection
88
+ request_parameter_list = request_parameters&.to_request_parameters
89
+ uri = to_absolute_uri(relative_path, request_parameter_list)
90
+ request_headers ||= []
91
+ add_generic_headers('DELETE', uri, request_headers, context)
92
+
93
+ response_status_code, response_headers, response_body = nil
94
+ connection.delete(uri, request_headers) do |status_code, headers, content|
95
+ response_status_code = status_code
96
+ response_headers = headers
97
+ response_body = content.read.force_encoding('UTF-8')
98
+ end
99
+ process_response(response_body, response_status_code, response_headers, response_type, relative_path, context)
100
+ end
101
+
102
+ # Performs a POST request to the Ingenico ePayments platform and returns the response as the given response type.
103
+ #
104
+ # @param relative_path [String] Path relative to the API endpoint
105
+ # @param request_headers [Array<Ingenico::Direct::SDK::RequestHeader>, nil] Optional array of request headers
106
+ # @param request_parameters [Ingenico::Direct::SDK::ParamRequest, nil] Optional request parameters
107
+ # @param request_body [Ingenico::Direct::SDK::DataObject] The optional request body
108
+ # @param response_type [Type] The response type.
109
+ # @param context [Ingenico::Direct::SDK::CallContext, nil] Optional call context.
110
+ # @return The response of the POST request as the given response type
111
+ # @raise [Ingenico::Direct::SDK::ResponseException] if the request could not be fulfilled successfully.
112
+ # This occurs for example if the request is not authenticated correctly
113
+ # @raise [Ingenico::Direct::SDK::NotFoundException] if the requested resource is not found
114
+ # @raise [Ingenico::Direct::SDK::CommunicationException] if there is an error in communicating with the Ingenico ePayments platform.
115
+ # This occurs for example if a timeout occurs.
116
+ def post(relative_path, request_headers, request_parameters, request_body, response_type, context)
117
+ request_parameter_list = request_parameters&.to_request_parameters
118
+ uri = to_absolute_uri(relative_path, request_parameter_list)
119
+ request_headers ||= []
120
+
121
+ body = nil
122
+ if request_body
123
+ request_headers.push(RequestHeader.new('Content-Type', 'application/json'))
124
+ body = @marshaller.marshal(request_body)
125
+ else
126
+ # Set the content-type, even though there is no body, to prevent the httpClient from
127
+ # adding a content-type header after authentication has been generated.
128
+ request_headers.push(RequestHeader.new('Content-Type', 'text/plain'))
129
+ end
130
+
131
+ add_generic_headers('POST', uri, request_headers, context)
132
+
133
+ response_status_code, response_headers, response_body = nil
134
+ @connection.post(uri, request_headers, body) do |status_code, headers, content|
135
+ response_status_code = status_code
136
+ response_headers = headers
137
+ response_body = content.read.force_encoding('UTF-8')
138
+ end
139
+ process_response(response_body, response_status_code, response_headers, response_type, relative_path, context)
140
+ end
141
+
142
+ # Performs a PUT request to the Ingenico ePayments platform and returns the response as the given response type.
143
+ #
144
+ # @param relative_path [String] Path relative to the API endpoint
145
+ # @param request_headers [Array<Ingenico::Direct::SDK::RequestHeader>, nil] Optional array of request headers
146
+ # @param request_parameters [Ingenico::Direct::SDK::ParamRequest, nil] Optional request parameters
147
+ # @param request_body [Ingenico::Direct::SDK::DataObject]
148
+ # The optional request body
149
+ # @param response_type [Type] The response type.
150
+ # @param context [Ingenico::Direct::SDK::CallContext, nil] Optional call context.
151
+ # @return The response of the PUT request as the given response type
152
+ # @raise [Ingenico::Direct::SDK::ResponseException] if the request could not be fulfilled successfully.
153
+ # This occurs for example if the request is not authenticated correctly
154
+ # @raise [Ingenico::Direct::SDK::NotFoundException] if the requested resource is not found
155
+ # @raise [Ingenico::Direct::SDK::CommunicationException] if there is an error in communicating with the Ingenico ePayments platform.
156
+ # This occurs for example if a timeout occurs.
157
+ def put(relative_path, request_headers, request_parameters, request_body, response_type, context)
158
+ request_parameter_list = request_parameters&.to_request_parameters
159
+ uri = to_absolute_uri(relative_path, request_parameter_list)
160
+ request_headers ||= []
161
+
162
+ body = nil
163
+ if request_body
164
+ request_headers.push(RequestHeader.new('Content-Type', 'application/json'))
165
+ body = @marshaller.marshal(request_body)
166
+ else
167
+ # Set the content-type, even though there is no body, to prevent the httpClient from
168
+ # adding a content-type header after authentication has been generated.
169
+ request_headers.push(RequestHeader.new('Content-Type', 'text/plain'))
170
+ end
171
+ add_generic_headers('PUT', uri, request_headers, context)
172
+
173
+ response_status_code, response_headers, response_body = nil
174
+ @connection.put(uri, request_headers, body) do |status_code, headers, content|
175
+ response_status_code = status_code
176
+ response_headers = headers
177
+ response_body = content.read.force_encoding('UTF-8')
178
+ end
179
+ process_response(response_body, response_status_code, response_headers, response_type, relative_path, context)
180
+ end
181
+
182
+ # Closes any connections idle for more than _idle_time_ seconds.
183
+ # Will not have any effect if the connection is not a pooled connection (an instance of {Ingenico::Direct::SDK::PooledConnection}).
184
+ def close_idle_connections(idle_time)
185
+ @connection.close_idle_connections(idle_time) if connection.is_a? PooledConnection
186
+ end
187
+
188
+ # Closes any connections that have expired.
189
+ # Will not have any effect if the connection is not a pooled connection (an instance of {Ingenico::Direct::SDK::PooledConnection}).
190
+ def close_expired_connections
191
+ @connection.close_expired_connections if connection.is_a? PooledConnection
192
+ end
193
+
194
+ # Enables logging outgoing requests and incoming responses by registering the _communicator_logger_.
195
+ # Note that only one logger can be registered at a time and calling _enable_logging_
196
+ # a second time will override the old logger instance with the new one.
197
+ #
198
+ # @param communicator_logger [Ingenico::Direct::SDK::Logging::CommunicatorLogger] The communicator logger the requests and responses are logged to
199
+ def enable_logging(communicator_logger)
200
+ @connection.enable_logging(communicator_logger)
201
+ end
202
+
203
+ # Disables logging by unregistering any previous logger that might be registered.
204
+ def disable_logging
205
+ @connection.disable_logging
206
+ end
207
+
208
+ # Frees networking resources by closing the underlying network connections.
209
+ # After calling _close_, any use of the _get_, _delete_, _post_ and _put_ methods will not function
210
+ # and likely result in an error.
211
+ def close
212
+ @connection.close
213
+ end
214
+
215
+
216
+ attr_reader :api_endpoint
217
+ attr_reader :connection
218
+ attr_reader :authenticator
219
+ attr_reader :meta_data_provider
220
+ attr_reader :marshaller
221
+
222
+ protected
223
+
224
+ # Constructs a full URL using the base URL and the given relative path and request_parameters.
225
+ # The returned URL is a *URI* object.
226
+ #
227
+ # @param relative_path [String] The relative path of the URL.
228
+ # @param request_parameters [Array<Ingenico::Direct::SDK::RequestParam>, nil] A list of request parameters that each have #name and #value
229
+ # which represent the parameter name and value respectively.
230
+ def to_absolute_uri(relative_path, request_parameters)
231
+ raise RuntimeError('api_endpoint should not contain a path') unless @api_endpoint.path.nil? || @api_endpoint.path.empty?
232
+
233
+ if @api_endpoint.userinfo || @api_endpoint.query || @api_endpoint.fragment
234
+ raise RuntimeError, 'api_endpoint should not contain user info, query or fragment'
235
+ end
236
+ absolute_path = relative_path.start_with?('/') ? relative_path : "/#{relative_path}"
237
+ uri = URI::HTTP.new(@api_endpoint.scheme, nil, @api_endpoint.host,
238
+ @api_endpoint.port, nil, absolute_path, nil, nil, nil)
239
+ request_parameters&.each do |nvp|
240
+ parameters = URI.decode_www_form(uri.query || '') << [nvp.name, nvp.value]
241
+ uri.query = URI.encode_www_form(parameters)
242
+ end
243
+ uri
244
+ end
245
+
246
+ # Adds several standard headers to the http headers.
247
+ # This method will add the 'Date' and 'Authorization' header;
248
+ # the 'X-GCS-Idempotence-Key' header will also be added if an idempotence context is given
249
+ #
250
+ # @param http_method [String] 'GET', 'DELETE', 'POST' or 'PUT' depending on the HTTP method being used
251
+ # @param uri [URI::HTTP] The full URI to the Ingenico ePayments platform,
252
+ # including the relative path and request parameters.
253
+ # @param request_headers [Array<Ingenico::Direct::SDK::RequestHeader>] List of request headers in which which new headers will be added
254
+ # @param context [Ingenico::Direct::SDK::CallContext, nil] object that will be used to produce
255
+ # an Idempotence header to prevent accidental request duplication.
256
+ def add_generic_headers(http_method, uri, request_headers, context = nil)
257
+ request_headers.concat(meta_data_provider.meta_data_headers)
258
+ request_headers.push(RequestHeader.new('Date', get_header_date_string))
259
+ if context&.idempotence_key
260
+ request_headers.push(RequestHeader.new('X-GCS-Idempotence-Key', context.idempotence_key))
261
+ end
262
+ authentication_signature = @authenticator.create_simple_authentication_signature(http_method, uri, request_headers)
263
+ request_headers.push(RequestHeader.new('Authorization', authentication_signature))
264
+ end
265
+
266
+ def get_header_date_string
267
+ Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
268
+ end
269
+
270
+ def process_response(body, status, headers, response_type, request_path, context)
271
+ update_context(headers, context) if context
272
+
273
+ throw_exception_if_necessary(body, status, headers, request_path)
274
+ @marshaller.unmarshal(body, response_type)
275
+ end
276
+
277
+ def update_context(headers, context)
278
+ context.idempotence_request_timestamp = ResponseHeader.get_header_value(headers, 'X-GCS-Idempotence-Request-Timestamp')
279
+ end
280
+
281
+ def throw_exception_if_necessary(body, status_code, headers, request_path)
282
+ return if status_code >= 200 && status_code < 300
283
+ raise ResponseException.new status_code, headers, body unless body && !is_json(headers)
284
+
285
+ cause = ResponseException.new(status_code, headers, body)
286
+ if status_code == 404
287
+ raise NotFoundException, cause, "The requested resource was not found; invalid path: #{request_path}"
288
+ end
289
+
290
+ raise CommunicationException, cause
291
+ end
292
+
293
+ private
294
+
295
+ def is_json(headers)
296
+ content_type = ResponseHeader.get_header_value(headers, 'Content-Type')
297
+ content_type.nil? || 'application/json'.casecmp(content_type).zero? ||
298
+ content_type.downcase.start_with?('application/json')
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,59 @@
1
+ module Ingenico::Direct::SDK
2
+
3
+ # A CommunicatorConfiguration stores all data used to initialize an {Ingenico::Direct::SDK::Communicator}.
4
+ #
5
+ # @attr [String] api_endpoint Base URL to the Ingenico ePayments platform
6
+ # @attr [String] api_key_id Identifier of the _secret_api_key_ used in authentication.
7
+ # @attr [String] secret_api_key Secret key used in authentication
8
+ # @attr [String] authorization_type String representing the authentication algorithm used
9
+ class CommunicatorConfiguration < EndpointConfiguration
10
+
11
+ # Creates a new CommunicatorConfiguration instance.
12
+ #
13
+ # If a _properties_ object is given, it will be parsed like a hash in order to read these attributes.
14
+ # If a value is given in both the _properties_ hash and as a separate parameter,
15
+ # the separate parameter will take precedence over the value in the properties.
16
+ #
17
+ # @param properties [Hash] hash that may contain any of the other parameters.
18
+ # @param api_endpoint [String] the base URL to the Ingenico ePayments platform.
19
+ # @param api_key_id [String] the identifier of the _secret_api_key_ used to authenticate requests.
20
+ # @param secret_api_key [String] the key used to authenticate requests sent to the Ingenico ePayments platform.
21
+ # @param authorization_type [String] string describing the authorization protocol to follow.
22
+ # @param connect_timeout [Integer] the number of seconds before a connection attempt with the Ingenico ePayments platform times out.
23
+ # @param socket_timeout [Integer] the number of seconds before a timeout occurs when transmitting data to or from the Ingenico ePayments platform.
24
+ # @param max_connections [Integer] the number of connections with the Ingenico ePayments platform that are kept alive in the connection pool.
25
+ # These connections will be reused when possible.
26
+ # @param proxy_configuration [Ingenico::Direct::SDK::ProxyConfiguration] stores the URL to a proxy to be used in all communication,
27
+ # or nil if no proxy should be used.
28
+ # @param integrator [String] name of the integrator
29
+ # @param shopping_cart_extension [Ingenico::Direct::SDK::Domain::ShoppingCartExtension] stores shopping cart-related metadata.
30
+ # @see EndpointConfiguration#initialize
31
+ def initialize(properties: nil, api_endpoint: nil, api_key_id: nil,
32
+ secret_api_key: nil, authorization_type: nil,
33
+ connect_timeout: nil, socket_timeout: nil,
34
+ max_connections: nil, proxy_configuration: nil,
35
+ integrator: nil, shopping_cart_extension: nil)
36
+ if properties
37
+ super(properties, 'direct.api')
38
+ @authorization_type = properties['direct.api.authorizationType'] ?
39
+ DefaultImpl::AuthorizationType.get_authorization(properties['direct.api.authorizationType']) :
40
+ DefaultImpl::AuthorizationType::V1HMAC
41
+ end
42
+ @api_endpoint = api_endpoint if api_endpoint
43
+ @api_key_id = api_key_id if api_key_id
44
+ @secret_api_key = secret_api_key if secret_api_key
45
+ @authorization_type = DefaultImpl::AuthorizationType.get_authorization(authorization_type) if authorization_type
46
+ @connect_timeout = connect_timeout if connect_timeout
47
+ @socket_timeout = socket_timeout if socket_timeout
48
+ @max_connections = max_connections if max_connections
49
+ @proxy_configuration = proxy_configuration if proxy_configuration
50
+ @integrator = integrator if integrator
51
+ @shopping_cart_extension = shopping_cart_extension if shopping_cart_extension
52
+ end
53
+
54
+ attr_accessor :api_endpoint
55
+ attr_accessor :api_key_id
56
+ attr_accessor :secret_api_key
57
+ attr_accessor :authorization_type
58
+ end
59
+ end