connect-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 (377) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +140 -0
  5. data/Rakefile +34 -0
  6. data/connect-sdk-ruby.gemspec +28 -0
  7. data/examples/merchant/example_configuration.yml +6 -0
  8. data/examples/merchant/hostedcheckouts/create_hosted_checkout_example.rb +53 -0
  9. data/examples/merchant/hostedcheckouts/get_hosted_checkout_example.rb +22 -0
  10. data/examples/merchant/payments/approve_payment_example.rb +42 -0
  11. data/examples/merchant/payments/cancel_approval_payment_example.rb +22 -0
  12. data/examples/merchant/payments/cancel_payment_example.rb +22 -0
  13. data/examples/merchant/payments/create_payment_example.rb +177 -0
  14. data/examples/merchant/payments/get_payment_example.rb +22 -0
  15. data/examples/merchant/payments/process_challenged_payment_example.rb +22 -0
  16. data/examples/merchant/payments/refund_payment_example.rb +85 -0
  17. data/examples/merchant/payments/tokenize_payment_example.rb +27 -0
  18. data/examples/merchant/payouts/approve_payout_example.rb +27 -0
  19. data/examples/merchant/payouts/cancel_approval_payout_example.rb +22 -0
  20. data/examples/merchant/payouts/cancel_payout_example.rb +22 -0
  21. data/examples/merchant/payouts/create_payout_example.rb +96 -0
  22. data/examples/merchant/payouts/get_payout_example.rb +22 -0
  23. data/examples/merchant/productgroups/get_payment_product_group_example.rb +32 -0
  24. data/examples/merchant/productgroups/get_payment_product_groups_example.rb +32 -0
  25. data/examples/merchant/products/get_directory_example.rb +28 -0
  26. data/examples/merchant/products/get_payment_product_example.rb +32 -0
  27. data/examples/merchant/products/get_payment_products_example.rb +32 -0
  28. data/examples/merchant/refunds/approve_refund_example.rb +27 -0
  29. data/examples/merchant/refunds/cancel_approval_refund_example.rb +22 -0
  30. data/examples/merchant/refunds/cancel_refund_example.rb +22 -0
  31. data/examples/merchant/refunds/get_refund_example.rb +22 -0
  32. data/examples/merchant/riskassessments/risk_assessment_bank_account_example.rb +54 -0
  33. data/examples/merchant/riskassessments/risk_assessment_cards_example.rb +114 -0
  34. data/examples/merchant/services/convert_amount_example.rb +29 -0
  35. data/examples/merchant/services/convert_bank_account_example.rb +34 -0
  36. data/examples/merchant/services/iin_details_example.rb +27 -0
  37. data/examples/merchant/services/test_connection_example.rb +22 -0
  38. data/examples/merchant/sessions/create_session_example.rb +34 -0
  39. data/examples/merchant/tokens/approve_sepa_direct_debit_token_example.rb +29 -0
  40. data/examples/merchant/tokens/create_token_example.rb +82 -0
  41. data/examples/merchant/tokens/delete_token_example.rb +27 -0
  42. data/examples/merchant/tokens/get_token_example.rb +22 -0
  43. data/examples/merchant/tokens/update_token_example.rb +76 -0
  44. data/lib/ingenico/connect/sdk.rb +27 -0
  45. data/lib/ingenico/connect/sdk/api_exception.rb +52 -0
  46. data/lib/ingenico/connect/sdk/api_resource.rb +126 -0
  47. data/lib/ingenico/connect/sdk/authenticator.rb +15 -0
  48. data/lib/ingenico/connect/sdk/authorization_exception.rb +13 -0
  49. data/lib/ingenico/connect/sdk/call_context.rb +26 -0
  50. data/lib/ingenico/connect/sdk/client.rb +92 -0
  51. data/lib/ingenico/connect/sdk/communication_exception.rb +15 -0
  52. data/lib/ingenico/connect/sdk/communicator.rb +277 -0
  53. data/lib/ingenico/connect/sdk/communicator_configuration.rb +98 -0
  54. data/lib/ingenico/connect/sdk/connection.rb +31 -0
  55. data/lib/ingenico/connect/sdk/data_object.rb +43 -0
  56. data/lib/ingenico/connect/sdk/declined_payment_exception.rb +44 -0
  57. data/lib/ingenico/connect/sdk/declined_payout_exception.rb +44 -0
  58. data/lib/ingenico/connect/sdk/declined_refund_exception.rb +46 -0
  59. data/lib/ingenico/connect/sdk/declined_transaction_exception.rb +16 -0
  60. data/lib/ingenico/connect/sdk/defaultimpl.rb +6 -0
  61. data/lib/ingenico/connect/sdk/defaultimpl/authorization_type.rb +18 -0
  62. data/lib/ingenico/connect/sdk/defaultimpl/default_authenticator.rb +106 -0
  63. data/lib/ingenico/connect/sdk/defaultimpl/default_connection.rb +242 -0
  64. data/lib/ingenico/connect/sdk/defaultimpl/default_marshaller.rb +35 -0
  65. data/lib/ingenico/connect/sdk/domain/definitions/abstract_order_status.rb +32 -0
  66. data/lib/ingenico/connect/sdk/domain/definitions/abstract_payment_method_specific_input.rb +32 -0
  67. data/lib/ingenico/connect/sdk/domain/definitions/additional_order_input_airline_data.rb +36 -0
  68. data/lib/ingenico/connect/sdk/domain/definitions/address.rb +81 -0
  69. data/lib/ingenico/connect/sdk/domain/definitions/airline_data.rb +165 -0
  70. data/lib/ingenico/connect/sdk/domain/definitions/airline_flight_leg.rb +102 -0
  71. data/lib/ingenico/connect/sdk/domain/definitions/amount_of_money.rb +39 -0
  72. data/lib/ingenico/connect/sdk/domain/definitions/bank_account.rb +32 -0
  73. data/lib/ingenico/connect/sdk/domain/definitions/bank_account_bban.rb +67 -0
  74. data/lib/ingenico/connect/sdk/domain/definitions/bank_account_iban.rb +32 -0
  75. data/lib/ingenico/connect/sdk/domain/definitions/card.rb +32 -0
  76. data/lib/ingenico/connect/sdk/domain/definitions/card_essentials.rb +39 -0
  77. data/lib/ingenico/connect/sdk/domain/definitions/card_fraud_results.rb +50 -0
  78. data/lib/ingenico/connect/sdk/domain/definitions/card_without_cvv.rb +39 -0
  79. data/lib/ingenico/connect/sdk/domain/definitions/company_information.rb +32 -0
  80. data/lib/ingenico/connect/sdk/domain/definitions/contact_details_base.rb +39 -0
  81. data/lib/ingenico/connect/sdk/domain/definitions/customer_base.rb +50 -0
  82. data/lib/ingenico/connect/sdk/domain/definitions/fraud_fields.rb +115 -0
  83. data/lib/ingenico/connect/sdk/domain/definitions/fraud_results.rb +32 -0
  84. data/lib/ingenico/connect/sdk/domain/definitions/fraud_results_retail_decisions.rb +46 -0
  85. data/lib/ingenico/connect/sdk/domain/definitions/key_value_pair.rb +39 -0
  86. data/lib/ingenico/connect/sdk/domain/definitions/order_status_output.rb +67 -0
  87. data/lib/ingenico/connect/sdk/domain/definitions/payment_product_filter.rb +51 -0
  88. data/lib/ingenico/connect/sdk/domain/definitions/personal_name_base.rb +46 -0
  89. data/lib/ingenico/connect/sdk/domain/definitions/result_do_risk_assessment.rb +61 -0
  90. data/lib/ingenico/connect/sdk/domain/definitions/retail_decisions_cc_fraud_check_output.rb +46 -0
  91. data/lib/ingenico/connect/sdk/domain/definitions/validation_bank_account_check.rb +46 -0
  92. data/lib/ingenico/connect/sdk/domain/definitions/validation_bank_account_output.rb +67 -0
  93. data/lib/ingenico/connect/sdk/domain/errors/api_error.rb +60 -0
  94. data/lib/ingenico/connect/sdk/domain/errors/error_response.rb +46 -0
  95. data/lib/ingenico/connect/sdk/domain/hostedcheckout/create_hosted_checkout_request.rb +102 -0
  96. data/lib/ingenico/connect/sdk/domain/hostedcheckout/create_hosted_checkout_response.rb +59 -0
  97. data/lib/ingenico/connect/sdk/domain/hostedcheckout/created_payment_output.rb +72 -0
  98. data/lib/ingenico/connect/sdk/domain/hostedcheckout/displayed_data.rb +53 -0
  99. data/lib/ingenico/connect/sdk/domain/hostedcheckout/get_hosted_checkout_response.rb +43 -0
  100. data/lib/ingenico/connect/sdk/domain/hostedcheckout/hosted_checkout_specific_input.rb +78 -0
  101. data/lib/ingenico/connect/sdk/domain/hostedcheckout/payment_product_filters_hosted_checkout.rb +53 -0
  102. data/lib/ingenico/connect/sdk/domain/metadata/shopping_cart_extension.rb +48 -0
  103. data/lib/ingenico/connect/sdk/domain/payment/abstract_payment_method_specific_output.rb +32 -0
  104. data/lib/ingenico/connect/sdk/domain/payment/additional_order_input.rb +72 -0
  105. data/lib/ingenico/connect/sdk/domain/payment/address_personal.rb +36 -0
  106. data/lib/ingenico/connect/sdk/domain/payment/approve_payment_card_payment_method_specific_output.rb +32 -0
  107. data/lib/ingenico/connect/sdk/domain/payment/approve_payment_non_sepa_direct_debit_payment_method_specific_input.rb +16 -0
  108. data/lib/ingenico/connect/sdk/domain/payment/approve_payment_payment_method_specific_input.rb +39 -0
  109. data/lib/ingenico/connect/sdk/domain/payment/approve_payment_request.rb +65 -0
  110. data/lib/ingenico/connect/sdk/domain/payment/approve_payment_sepa_direct_debit_payment_method_specific_input.rb +16 -0
  111. data/lib/ingenico/connect/sdk/domain/payment/bank_transfer_payment_method_specific_input.rb +16 -0
  112. data/lib/ingenico/connect/sdk/domain/payment/bank_transfer_payment_method_specific_input_base.rb +32 -0
  113. data/lib/ingenico/connect/sdk/domain/payment/bank_transfer_payment_method_specific_output.rb +16 -0
  114. data/lib/ingenico/connect/sdk/domain/payment/cancel_approval_payment_response.rb +36 -0
  115. data/lib/ingenico/connect/sdk/domain/payment/cancel_payment_card_payment_method_specific_output.rb +32 -0
  116. data/lib/ingenico/connect/sdk/domain/payment/cancel_payment_response.rb +47 -0
  117. data/lib/ingenico/connect/sdk/domain/payment/card_payment_method_specific_input.rb +61 -0
  118. data/lib/ingenico/connect/sdk/domain/payment/card_payment_method_specific_input_base.rb +60 -0
  119. data/lib/ingenico/connect/sdk/domain/payment/card_payment_method_specific_output.rb +65 -0
  120. data/lib/ingenico/connect/sdk/domain/payment/cash_payment_method_specific_input.rb +47 -0
  121. data/lib/ingenico/connect/sdk/domain/payment/cash_payment_method_specific_input_base.rb +16 -0
  122. data/lib/ingenico/connect/sdk/domain/payment/cash_payment_method_specific_output.rb +16 -0
  123. data/lib/ingenico/connect/sdk/domain/payment/cash_payment_product1503_specific_input.rb +32 -0
  124. data/lib/ingenico/connect/sdk/domain/payment/cash_payment_product1504_specific_input.rb +32 -0
  125. data/lib/ingenico/connect/sdk/domain/payment/contact_details.rb +39 -0
  126. data/lib/ingenico/connect/sdk/domain/payment/create_payment_request.rb +131 -0
  127. data/lib/ingenico/connect/sdk/domain/payment/create_payment_response.rb +16 -0
  128. data/lib/ingenico/connect/sdk/domain/payment/create_payment_result.rb +58 -0
  129. data/lib/ingenico/connect/sdk/domain/payment/customer.rb +83 -0
  130. data/lib/ingenico/connect/sdk/domain/payment/external_cardholder_authentication_data.rb +60 -0
  131. data/lib/ingenico/connect/sdk/domain/payment/invoice_payment_method_specific_input.rb +32 -0
  132. data/lib/ingenico/connect/sdk/domain/payment/invoice_payment_method_specific_output.rb +16 -0
  133. data/lib/ingenico/connect/sdk/domain/payment/level3_summary_data.rb +46 -0
  134. data/lib/ingenico/connect/sdk/domain/payment/line_item.rb +58 -0
  135. data/lib/ingenico/connect/sdk/domain/payment/line_item_invoice_data.rb +60 -0
  136. data/lib/ingenico/connect/sdk/domain/payment/line_item_level3_interchange_information.rb +81 -0
  137. data/lib/ingenico/connect/sdk/domain/payment/merchant_action.rb +64 -0
  138. data/lib/ingenico/connect/sdk/domain/payment/non_sepa_direct_debit_payment_method_specific_input.rb +71 -0
  139. data/lib/ingenico/connect/sdk/domain/payment/non_sepa_direct_debit_payment_method_specific_output.rb +36 -0
  140. data/lib/ingenico/connect/sdk/domain/payment/non_sepa_direct_debit_payment_product705_specific_input.rb +50 -0
  141. data/lib/ingenico/connect/sdk/domain/payment/order.rb +83 -0
  142. data/lib/ingenico/connect/sdk/domain/payment/order_approve_payment.rb +47 -0
  143. data/lib/ingenico/connect/sdk/domain/payment/order_invoice_data.rb +59 -0
  144. data/lib/ingenico/connect/sdk/domain/payment/order_output.rb +47 -0
  145. data/lib/ingenico/connect/sdk/domain/payment/order_references.rb +57 -0
  146. data/lib/ingenico/connect/sdk/domain/payment/order_references_approve_payment.rb +32 -0
  147. data/lib/ingenico/connect/sdk/domain/payment/order_type_information.rb +39 -0
  148. data/lib/ingenico/connect/sdk/domain/payment/payment.rb +54 -0
  149. data/lib/ingenico/connect/sdk/domain/payment/payment_approval_response.rb +47 -0
  150. data/lib/ingenico/connect/sdk/domain/payment/payment_creation_output.rb +39 -0
  151. data/lib/ingenico/connect/sdk/domain/payment/payment_creation_references.rb +39 -0
  152. data/lib/ingenico/connect/sdk/domain/payment/payment_error_response.rb +57 -0
  153. data/lib/ingenico/connect/sdk/domain/payment/payment_output.rb +116 -0
  154. data/lib/ingenico/connect/sdk/domain/payment/payment_product836_specific_output.rb +32 -0
  155. data/lib/ingenico/connect/sdk/domain/payment/payment_product840_customer_account.rb +88 -0
  156. data/lib/ingenico/connect/sdk/domain/payment/payment_product840_specific_output.rb +47 -0
  157. data/lib/ingenico/connect/sdk/domain/payment/payment_references.rb +67 -0
  158. data/lib/ingenico/connect/sdk/domain/payment/payment_response.rb +16 -0
  159. data/lib/ingenico/connect/sdk/domain/payment/payment_status_output.rb +39 -0
  160. data/lib/ingenico/connect/sdk/domain/payment/personal_information.rb +50 -0
  161. data/lib/ingenico/connect/sdk/domain/payment/personal_name.rb +32 -0
  162. data/lib/ingenico/connect/sdk/domain/payment/redirect_data.rb +39 -0
  163. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_method_specific_input.rb +72 -0
  164. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_method_specific_input_base.rb +39 -0
  165. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_method_specific_output.rb +58 -0
  166. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_product809_specific_input.rb +39 -0
  167. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_product816_specific_input.rb +36 -0
  168. data/lib/ingenico/connect/sdk/domain/payment/redirect_payment_product882_specific_input.rb +32 -0
  169. data/lib/ingenico/connect/sdk/domain/payment/refund_bank_method_specific_output.rb +16 -0
  170. data/lib/ingenico/connect/sdk/domain/payment/refund_card_method_specific_output.rb +16 -0
  171. data/lib/ingenico/connect/sdk/domain/payment/refund_e_wallet_method_specific_output.rb +36 -0
  172. data/lib/ingenico/connect/sdk/domain/payment/refund_method_specific_output.rb +39 -0
  173. data/lib/ingenico/connect/sdk/domain/payment/refund_output.rb +72 -0
  174. data/lib/ingenico/connect/sdk/domain/payment/refund_payment_product840_customer_account.rb +46 -0
  175. data/lib/ingenico/connect/sdk/domain/payment/refund_payment_product840_specific_output.rb +36 -0
  176. data/lib/ingenico/connect/sdk/domain/payment/sepa_direct_debit_payment_method_specific_input.rb +60 -0
  177. data/lib/ingenico/connect/sdk/domain/payment/sepa_direct_debit_payment_method_specific_output.rb +36 -0
  178. data/lib/ingenico/connect/sdk/domain/payment/three_d_secure_results.rb +46 -0
  179. data/lib/ingenico/connect/sdk/domain/payment/tokenize_payment_request.rb +32 -0
  180. data/lib/ingenico/connect/sdk/domain/payout/approve_payout_request.rb +32 -0
  181. data/lib/ingenico/connect/sdk/domain/payout/create_payout_request.rb +101 -0
  182. data/lib/ingenico/connect/sdk/domain/payout/payout_customer.rb +76 -0
  183. data/lib/ingenico/connect/sdk/domain/payout/payout_error_response.rb +57 -0
  184. data/lib/ingenico/connect/sdk/domain/payout/payout_references.rb +46 -0
  185. data/lib/ingenico/connect/sdk/domain/payout/payout_response.rb +16 -0
  186. data/lib/ingenico/connect/sdk/domain/payout/payout_result.rb +54 -0
  187. data/lib/ingenico/connect/sdk/domain/product/account_on_file.rb +64 -0
  188. data/lib/ingenico/connect/sdk/domain/product/account_on_file_attribute.rb +39 -0
  189. data/lib/ingenico/connect/sdk/domain/product/account_on_file_display_hints.rb +46 -0
  190. data/lib/ingenico/connect/sdk/domain/product/directory.rb +39 -0
  191. data/lib/ingenico/connect/sdk/domain/product/directory_entry.rb +59 -0
  192. data/lib/ingenico/connect/sdk/domain/product/empty_validator.rb +16 -0
  193. data/lib/ingenico/connect/sdk/domain/product/fixed_list_validator.rb +38 -0
  194. data/lib/ingenico/connect/sdk/domain/product/label_template_element.rb +39 -0
  195. data/lib/ingenico/connect/sdk/domain/product/length_validator.rb +39 -0
  196. data/lib/ingenico/connect/sdk/domain/product/payment_product.rb +134 -0
  197. data/lib/ingenico/connect/sdk/domain/product/payment_product_display_hints.rb +46 -0
  198. data/lib/ingenico/connect/sdk/domain/product/payment_product_field.rb +61 -0
  199. data/lib/ingenico/connect/sdk/domain/product/payment_product_field_data_restrictions.rb +43 -0
  200. data/lib/ingenico/connect/sdk/domain/product/payment_product_field_display_hints.rb +96 -0
  201. data/lib/ingenico/connect/sdk/domain/product/payment_product_field_form_element.rb +46 -0
  202. data/lib/ingenico/connect/sdk/domain/product/payment_product_field_tooltip.rb +39 -0
  203. data/lib/ingenico/connect/sdk/domain/product/payment_product_field_validators.rb +100 -0
  204. data/lib/ingenico/connect/sdk/domain/product/payment_product_group.rb +71 -0
  205. data/lib/ingenico/connect/sdk/domain/product/payment_product_group_response.rb +16 -0
  206. data/lib/ingenico/connect/sdk/domain/product/payment_product_groups.rb +39 -0
  207. data/lib/ingenico/connect/sdk/domain/product/payment_product_response.rb +16 -0
  208. data/lib/ingenico/connect/sdk/domain/product/payment_products.rb +39 -0
  209. data/lib/ingenico/connect/sdk/domain/product/range_validator.rb +39 -0
  210. data/lib/ingenico/connect/sdk/domain/product/regular_expression_validator.rb +32 -0
  211. data/lib/ingenico/connect/sdk/domain/product/value_mapping_element.rb +39 -0
  212. data/lib/ingenico/connect/sdk/domain/refund/approve_refund_request.rb +32 -0
  213. data/lib/ingenico/connect/sdk/domain/refund/bank_account_bban_refund.rb +39 -0
  214. data/lib/ingenico/connect/sdk/domain/refund/bank_refund_method_specific_input.rb +54 -0
  215. data/lib/ingenico/connect/sdk/domain/refund/refund_customer.rb +58 -0
  216. data/lib/ingenico/connect/sdk/domain/refund/refund_error_response.rb +57 -0
  217. data/lib/ingenico/connect/sdk/domain/refund/refund_references.rb +32 -0
  218. data/lib/ingenico/connect/sdk/domain/refund/refund_request.rb +76 -0
  219. data/lib/ingenico/connect/sdk/domain/refund/refund_response.rb +16 -0
  220. data/lib/ingenico/connect/sdk/domain/refund/refund_result.rb +54 -0
  221. data/lib/ingenico/connect/sdk/domain/riskassessments/customer_risk_assessment.rb +65 -0
  222. data/lib/ingenico/connect/sdk/domain/riskassessments/order_risk_assessment.rb +58 -0
  223. data/lib/ingenico/connect/sdk/domain/riskassessments/personal_information_risk_assessment.rb +36 -0
  224. data/lib/ingenico/connect/sdk/domain/riskassessments/personal_name_risk_assessment.rb +16 -0
  225. data/lib/ingenico/connect/sdk/domain/riskassessments/risk_assessment.rb +54 -0
  226. data/lib/ingenico/connect/sdk/domain/riskassessments/risk_assessment_bank_account.rb +47 -0
  227. data/lib/ingenico/connect/sdk/domain/riskassessments/risk_assessment_card.rb +36 -0
  228. data/lib/ingenico/connect/sdk/domain/riskassessments/risk_assessment_response.rb +39 -0
  229. data/lib/ingenico/connect/sdk/domain/services/bank_data.rb +53 -0
  230. data/lib/ingenico/connect/sdk/domain/services/bank_details.rb +47 -0
  231. data/lib/ingenico/connect/sdk/domain/services/bank_details_request.rb +16 -0
  232. data/lib/ingenico/connect/sdk/domain/services/bank_details_response.rb +69 -0
  233. data/lib/ingenico/connect/sdk/domain/services/convert_amount.rb +32 -0
  234. data/lib/ingenico/connect/sdk/domain/services/get_iin_details_request.rb +43 -0
  235. data/lib/ingenico/connect/sdk/domain/services/get_iin_details_response.rb +60 -0
  236. data/lib/ingenico/connect/sdk/domain/services/iin_detail.rb +39 -0
  237. data/lib/ingenico/connect/sdk/domain/services/payment_context.rb +50 -0
  238. data/lib/ingenico/connect/sdk/domain/services/swift.rb +95 -0
  239. data/lib/ingenico/connect/sdk/domain/services/test_connection.rb +32 -0
  240. data/lib/ingenico/connect/sdk/domain/sessions/payment_product_filters_client_session.rb +46 -0
  241. data/lib/ingenico/connect/sdk/domain/sessions/session_request.rb +49 -0
  242. data/lib/ingenico/connect/sdk/domain/sessions/session_response.rb +59 -0
  243. data/lib/ingenico/connect/sdk/domain/token/abstract_token.rb +32 -0
  244. data/lib/ingenico/connect/sdk/domain/token/approve_token_request.rb +16 -0
  245. data/lib/ingenico/connect/sdk/domain/token/contact_details_token.rb +16 -0
  246. data/lib/ingenico/connect/sdk/domain/token/create_token_request.rb +76 -0
  247. data/lib/ingenico/connect/sdk/domain/token/create_token_response.rb +39 -0
  248. data/lib/ingenico/connect/sdk/domain/token/creditor.rb +102 -0
  249. data/lib/ingenico/connect/sdk/domain/token/customer_token.rb +47 -0
  250. data/lib/ingenico/connect/sdk/domain/token/customer_token_with_contact_details.rb +36 -0
  251. data/lib/ingenico/connect/sdk/domain/token/debtor.rb +102 -0
  252. data/lib/ingenico/connect/sdk/domain/token/mandate_approval.rb +46 -0
  253. data/lib/ingenico/connect/sdk/domain/token/mandate_non_sepa_direct_debit.rb +36 -0
  254. data/lib/ingenico/connect/sdk/domain/token/mandate_sepa_direct_debit.rb +36 -0
  255. data/lib/ingenico/connect/sdk/domain/token/mandate_sepa_direct_debit_with_mandate_id.rb +32 -0
  256. data/lib/ingenico/connect/sdk/domain/token/mandate_sepa_direct_debit_without_creditor.rb +79 -0
  257. data/lib/ingenico/connect/sdk/domain/token/personal_information_token.rb +36 -0
  258. data/lib/ingenico/connect/sdk/domain/token/personal_name_token.rb +16 -0
  259. data/lib/ingenico/connect/sdk/domain/token/token_card.rb +47 -0
  260. data/lib/ingenico/connect/sdk/domain/token/token_card_data.rb +50 -0
  261. data/lib/ingenico/connect/sdk/domain/token/token_e_wallet.rb +47 -0
  262. data/lib/ingenico/connect/sdk/domain/token/token_e_wallet_data.rb +32 -0
  263. data/lib/ingenico/connect/sdk/domain/token/token_non_sepa_direct_debit.rb +47 -0
  264. data/lib/ingenico/connect/sdk/domain/token/token_non_sepa_direct_debit_payment_product705_specific_data.rb +43 -0
  265. data/lib/ingenico/connect/sdk/domain/token/token_response.rb +83 -0
  266. data/lib/ingenico/connect/sdk/domain/token/token_sepa_direct_debit.rb +47 -0
  267. data/lib/ingenico/connect/sdk/domain/token/token_sepa_direct_debit_without_creditor.rb +47 -0
  268. data/lib/ingenico/connect/sdk/domain/token/update_token_request.rb +76 -0
  269. data/lib/ingenico/connect/sdk/endpoint_configuration.rb +139 -0
  270. data/lib/ingenico/connect/sdk/exceptions.rb +8 -0
  271. data/lib/ingenico/connect/sdk/factory.rb +200 -0
  272. data/lib/ingenico/connect/sdk/global_collect_exception.rb +15 -0
  273. data/lib/ingenico/connect/sdk/idempotence_exception.rb +24 -0
  274. data/lib/ingenico/connect/sdk/logging.rb +10 -0
  275. data/lib/ingenico/connect/sdk/logging/communicator_logger.rb +19 -0
  276. data/lib/ingenico/connect/sdk/logging/log_message_builder.rb +61 -0
  277. data/lib/ingenico/connect/sdk/logging/logging_capable.rb +19 -0
  278. data/lib/ingenico/connect/sdk/logging/logging_util.rb +298 -0
  279. data/lib/ingenico/connect/sdk/logging/request_log_message_builder.rb +42 -0
  280. data/lib/ingenico/connect/sdk/logging/response_log_message_builder.rb +34 -0
  281. data/lib/ingenico/connect/sdk/logging/ruby_communicator_logger.rb +58 -0
  282. data/lib/ingenico/connect/sdk/logging/stdout_communicator_logger.rb +36 -0
  283. data/lib/ingenico/connect/sdk/marshaller.rb +19 -0
  284. data/lib/ingenico/connect/sdk/marshaller_syntax_exception.rb +6 -0
  285. data/lib/ingenico/connect/sdk/merchant/hostedcheckouts/hostedcheckouts_client.rb +88 -0
  286. data/lib/ingenico/connect/sdk/merchant/merchant_client.rb +110 -0
  287. data/lib/ingenico/connect/sdk/merchant/payments/payments_client.rb +319 -0
  288. data/lib/ingenico/connect/sdk/merchant/payouts/payouts_client.rb +197 -0
  289. data/lib/ingenico/connect/sdk/merchant/productgroups/find_productgroups_params.rb +55 -0
  290. data/lib/ingenico/connect/sdk/merchant/productgroups/get_productgroup_params.rb +55 -0
  291. data/lib/ingenico/connect/sdk/merchant/productgroups/productgroups_client.rb +90 -0
  292. data/lib/ingenico/connect/sdk/merchant/products/directory_params.rb +31 -0
  293. data/lib/ingenico/connect/sdk/merchant/products/find_products_params.rb +55 -0
  294. data/lib/ingenico/connect/sdk/merchant/products/get_product_params.rb +55 -0
  295. data/lib/ingenico/connect/sdk/merchant/products/products_client.rb +124 -0
  296. data/lib/ingenico/connect/sdk/merchant/refunds/refunds_client.rb +154 -0
  297. data/lib/ingenico/connect/sdk/merchant/riskassessments/riskassessments_client.rb +85 -0
  298. data/lib/ingenico/connect/sdk/merchant/services/convert_amount_params.rb +35 -0
  299. data/lib/ingenico/connect/sdk/merchant/services/services_client.rb +149 -0
  300. data/lib/ingenico/connect/sdk/merchant/sessions/sessions_client.rb +55 -0
  301. data/lib/ingenico/connect/sdk/merchant/tokens/delete_token_params.rb +27 -0
  302. data/lib/ingenico/connect/sdk/merchant/tokens/tokens_client.rb +192 -0
  303. data/lib/ingenico/connect/sdk/meta_data_provider.rb +152 -0
  304. data/lib/ingenico/connect/sdk/modules.rb +130 -0
  305. data/lib/ingenico/connect/sdk/not_found_exception.rb +19 -0
  306. data/lib/ingenico/connect/sdk/param_request.rb +33 -0
  307. data/lib/ingenico/connect/sdk/pooled_connection.rb +21 -0
  308. data/lib/ingenico/connect/sdk/proxy_configuration.rb +75 -0
  309. data/lib/ingenico/connect/sdk/reference_exception.rb +14 -0
  310. data/lib/ingenico/connect/sdk/request_header.rb +25 -0
  311. data/lib/ingenico/connect/sdk/request_param.rb +24 -0
  312. data/lib/ingenico/connect/sdk/response.rb +62 -0
  313. data/lib/ingenico/connect/sdk/response_exception.rb +54 -0
  314. data/lib/ingenico/connect/sdk/response_header.rb +25 -0
  315. data/lib/ingenico/connect/sdk/session.rb +39 -0
  316. data/lib/ingenico/connect/sdk/validation_exception.rb +14 -0
  317. data/spec/comparable_extension.rb +29 -0
  318. data/spec/fixtures/resources/defaultimpl/convertAmount.json +3 -0
  319. data/spec/fixtures/resources/defaultimpl/createPayment.failure.invalidCardNumber.json +11 -0
  320. data/spec/fixtures/resources/defaultimpl/createPayment.failure.rejected.json +48 -0
  321. data/spec/fixtures/resources/defaultimpl/createPayment.json +40 -0
  322. data/spec/fixtures/resources/defaultimpl/idempotence_duplicate_failure.json +8 -0
  323. data/spec/fixtures/resources/defaultimpl/idempotence_rejected.json +46 -0
  324. data/spec/fixtures/resources/defaultimpl/idempotence_success.json +39 -0
  325. data/spec/fixtures/resources/defaultimpl/notFound.html +1 -0
  326. data/spec/fixtures/resources/defaultimpl/testConnection.json +3 -0
  327. data/spec/fixtures/resources/defaultimpl/unknownServerError.json +10 -0
  328. data/spec/fixtures/resources/logging/bodyNoObfuscation.json +17 -0
  329. data/spec/fixtures/resources/logging/bodyWithBinObfuscated.json +3 -0
  330. data/spec/fixtures/resources/logging/bodyWithBinOriginal.json +3 -0
  331. data/spec/fixtures/resources/logging/bodyWithCardObfuscated.json +21 -0
  332. data/spec/fixtures/resources/logging/bodyWithCardOriginal.json +21 -0
  333. data/spec/fixtures/resources/logging/bodyWithIbanObfuscated.json +19 -0
  334. data/spec/fixtures/resources/logging/bodyWithIbanOriginal.json +19 -0
  335. data/spec/fixtures/resources/payment/duplicate_request.json +8 -0
  336. data/spec/fixtures/resources/payment/invalid_authorization.json +9 -0
  337. data/spec/fixtures/resources/payment/invalid_request.json +11 -0
  338. data/spec/fixtures/resources/payment/method_not_allowed.html +1 -0
  339. data/spec/fixtures/resources/payment/not_found.html +1 -0
  340. data/spec/fixtures/resources/payment/pending_approval.json +39 -0
  341. data/spec/fixtures/resources/payment/rejected.json +46 -0
  342. data/spec/fixtures/resources/properties.proxy.yml +13 -0
  343. data/spec/fixtures/resources/properties.yml +7 -0
  344. data/spec/integration/connection_pooling_spec.rb +78 -0
  345. data/spec/integration/convert_amount_spec.rb +25 -0
  346. data/spec/integration/idempotence_spec.rb +59 -0
  347. data/spec/integration/multiline_header_spec.rb +30 -0
  348. data/spec/integration/payment_product_groups_spec.rb +23 -0
  349. data/spec/integration/payment_products_spec.rb +22 -0
  350. data/spec/integration/risk_assessments_spec.rb +37 -0
  351. data/spec/integration/sdk_proxy_spec.rb +89 -0
  352. data/spec/integration/token_spec.rb +42 -0
  353. data/spec/integration_setup.rb +50 -0
  354. data/spec/lib/client_spec.rb +69 -0
  355. data/spec/lib/communicator_configuration_spec.rb +179 -0
  356. data/spec/lib/communicator_spec.rb +31 -0
  357. data/spec/lib/defaultimpl/default_authenticator_spec.rb +74 -0
  358. data/spec/lib/defaultimpl/default_connection_idempotence_spec.rb +142 -0
  359. data/spec/lib/defaultimpl/default_connection_logger_spec.rb +526 -0
  360. data/spec/lib/defaultimpl/default_connection_spec.rb +334 -0
  361. data/spec/lib/defaultimpl/default_marshaller_spec.rb +36 -0
  362. data/spec/lib/factory_spec.rb +41 -0
  363. data/spec/lib/logging/header_obfuscator_spec.rb +51 -0
  364. data/spec/lib/logging/logging_util_spec.rb +143 -0
  365. data/spec/lib/logging/obfuscator_spec.rb +52 -0
  366. data/spec/lib/logging/ruby_communicator_logger_spec.rb +84 -0
  367. data/spec/lib/logging/stdout_communicator_logger_spec.rb +64 -0
  368. data/spec/lib/logging/value_obfuscator_spec.rb +95 -0
  369. data/spec/lib/meta_data_provider_spec.rb +71 -0
  370. data/spec/lib/payments_client_spec.rb +157 -0
  371. data/spec/lib/requestparams/delete_params_spec.rb +21 -0
  372. data/spec/lib/requestparams/directory_params_spec.rb +27 -0
  373. data/spec/lib/requestparams/find_params_spec.rb +58 -0
  374. data/spec/lib/requestparams/get_params_spec.rb +59 -0
  375. data/spec/lib/requestparams/param_request_spec.rb +57 -0
  376. data/spec/spec_helper.rb +23 -0
  377. metadata +565 -0
@@ -0,0 +1,31 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # Class used to communicate using the HTTP (or HTTPS) protocol.
4
+ # Performs GET, DELETE, POST and PUT requests given a target uri and request headers.
5
+ # @see Ingenico::Connect::SDK::DefaultImpl::DefaultConnection
6
+ class Connection
7
+ include Ingenico::Connect::SDK::Logging::LoggingCapable
8
+
9
+ # Performs a GET request to _uri_ using _request_headers_ and returns the response as a {Ingenico::Connect::SDK::Response} object
10
+ def get(uri, request_headers)
11
+ raise NotImplementedError
12
+ end
13
+
14
+ # Performs a DELETE request to _uri_ using _request_headers_ and returns the response as a {Ingenico::Connect::SDK::Response} object
15
+ def delete(uri, request_headers)
16
+ raise NotImplementedError
17
+ end
18
+
19
+ # Performs a POST request to _uri_ using _request_headers_ and _body_.
20
+ # Returns the response as a {Ingenico::Connect::SDK::Response} object
21
+ def post(uri, request_headers, body)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ # Performs a PUT request to _uri_ using _request_headers_ and _body_.
26
+ # Returns the response as a {Ingenico::Connect::SDK::Response} object
27
+ def put(uri, request_headers, body)
28
+ raise NotImplementedError
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,43 @@
1
+ require 'json'
2
+
3
+ module Ingenico::Connect::SDK
4
+
5
+ # Base class for all SDK data objects, supports marshalling and unmarshalling the data object to and from JSON.
6
+ class DataObject
7
+
8
+ # Returns a hash representation of the DataObject.
9
+ # The hash contains camelCase representations of the variables, and their values.
10
+ # Should be overridden to add all instance variables of the object.
11
+ def to_h
12
+ {}
13
+ end
14
+
15
+ # Create a new instance of this object (DataObject or descendant)
16
+ # from a hash containing attribute values in camelCase.
17
+ # Note that the hash contains Strings as keys instead of more commonly used tokens.
18
+ def self.new_from_hash(hash)
19
+ obj = self.new
20
+ obj.from_hash(hash)
21
+ obj
22
+ end
23
+
24
+ # Set attributes from values in parameter hash.
25
+ # Should be overridden by descendants in order to properly restore their attributes from the hash.
26
+ # Note that the hash contains Strings as keys instead of more commonly used tokens.
27
+ def from_hash(hash)
28
+ end
29
+
30
+ private
31
+
32
+ # Adds a serializable hash or array representation of _value_ to _hash_ keyed under _key_
33
+ def add_to_hash(hash, key, value)
34
+ if value.is_a?(Array) # For arrays, convert the elements to hash representations
35
+ hash[key] = value.collect{|val| if val.is_a?(DataObject); val.to_h else val end}
36
+ elsif value.is_a?(DataObject)
37
+ hash[key] = value.to_h
38
+ elsif !value.nil?
39
+ hash[key] = value
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,44 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # Indicates that a payment is declined by the GlobalCollect platform or one of its downstream partners/acquirers.
4
+ class DeclinedPaymentException < DeclinedTransactionException
5
+
6
+ # Create a new DeclinedPaymentException.
7
+ # @see ApiException#initialize
8
+ def initialize(status_code, response_body, errors)
9
+ if errors.nil?
10
+ super(status_code, response_body, nil, nil, build_message(errors))
11
+ else
12
+ super(status_code, response_body, errors.error_id, errors.errors,
13
+ build_message(errors))
14
+ end
15
+ @errors = errors
16
+ end
17
+
18
+ # The declined payment result returned by the GlobalCollect platform.
19
+ # Given as a {Ingenico::Connect::SDK::Domain::Payment::CreatePaymentResult} object.
20
+ def payment_result
21
+ if @errors.nil?
22
+ nil
23
+ else
24
+ @errors.payment_result
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def build_message(errors)
31
+ if !errors.nil? && !errors.payment_result.nil?
32
+ payment = errors.payment_result.payment
33
+ else
34
+ payment = nil
35
+ end
36
+ if payment.nil?
37
+ 'the GlobalCollect platform returned a declined payment response'
38
+ else
39
+ "declined payment '" + payment.id + "' with status '" +
40
+ payment.status + "'"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # Indicates that a payout is declined by the GlobalCollect platform or one of its downstream partners/acquirers.
4
+ class DeclinedPayoutException < DeclinedTransactionException
5
+
6
+ # Create a new DeclinedPayoutException.
7
+ # @see ApiException#initialize
8
+ def initialize(status_code, response_body, errors)
9
+ if errors.nil?
10
+ super(status_code, response_body, nil, nil, build_message(errors))
11
+ else
12
+ super(status_code, response_body, errors.error_id, errors.errors,
13
+ build_message(errors))
14
+ end
15
+ @errors = errors
16
+ end
17
+
18
+ # The declined payout result as returned by the GlobalCollect platform.
19
+ # Given as a {Ingenico::Connect::SDK::Domain::Payout::PayoutResult} object.
20
+ def payout_result
21
+ if @errors.nil?
22
+ nil
23
+ else
24
+ @errors.payout_result
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def build_message(errors)
31
+ if !errors.nil?
32
+ payout = errors.payout_result
33
+ else
34
+ payout = nil
35
+ end
36
+ if payout.nil?
37
+ 'the GlobalCollect platform returned a declined payout response'
38
+ else
39
+ "declined payment '" + payout.id + "' with status '" +
40
+ payout.status + "'"
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,46 @@
1
+ require 'ingenico/connect/sdk/declined_transaction_exception'
2
+
3
+ module Ingenico::Connect::SDK
4
+
5
+ # Indicates that a refund is declined by the GlobalCollect platform or one of its downstream partners/acquirers.
6
+ class DeclinedRefundException < DeclinedTransactionException
7
+
8
+ # Create a new DeclinedRefundException
9
+ # @see ApiException#initialize
10
+ def initialize(status_code, response_body, errors)
11
+ if errors.nil?
12
+ super(status_code, response_body, nil, nil, build_message(errors))
13
+ else
14
+ super(status_code, response_body, errors.error_id, errors.errors,
15
+ build_message(errors))
16
+ end
17
+ @errors = errors
18
+ end
19
+
20
+ # The declined refund result as returned by the GlobalCollect platform.
21
+ # Given as a {Ingenico::Connect::SDK::Domain::Refund::RefundResult} object.
22
+ def refund_result
23
+ if @errors.nil?
24
+ nil
25
+ else
26
+ @errors.refund_result
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def build_message(errors)
33
+ if !errors.nil?
34
+ refund = errors.refund_result
35
+ else
36
+ refund = nil
37
+ end
38
+ if refund.nil?
39
+ 'the GlobalCollect platform returned a declined refund response'
40
+ else
41
+ "declined refund '" + refund.id + "' with status '" +
42
+ refund.status + "'"
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # Indicates that a transaction is declined by the GlobalCollect platform or one of its downstream partners/acquirers.
4
+ class DeclinedTransactionException < ApiException
5
+
6
+ # Create a new DeclinedTransactionException.
7
+ # @see ApiException#initialize
8
+ def initialize(status_code, response_body, error_id, errors, message=FALSE)
9
+ if message == FALSE
10
+ super(status_code, response_body, error_id, errors)
11
+ else
12
+ super(status_code, response_body, error_id, errors, message)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ prefix = 'ingenico/connect/sdk/defaultimpl/'
2
+
3
+ require prefix + 'authorization_type'
4
+ require prefix + 'default_marshaller'
5
+ require prefix + 'default_connection'
6
+ require prefix + 'default_authenticator'
@@ -0,0 +1,18 @@
1
+ module Ingenico::Connect::SDK
2
+ module DefaultImpl
3
+
4
+ # Contains all authentication schemes supported by the GlobabCollect platform.
5
+ class AuthorizationType
6
+ V1HMAC = 'v1HMAC'
7
+
8
+ # Returns the authorization string that belongs to the parameter _authorization_, or _nil_ if not found.
9
+ def self.get_authorization(authorization)
10
+ authorization if authorization == 'v1HMAC'
11
+ end
12
+
13
+ def self.get_signature_string
14
+ V1HMAC
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,106 @@
1
+ require 'openssl' # for HMAC-SHA256
2
+ require 'base64'
3
+
4
+ module Ingenico::Connect::SDK
5
+ module DefaultImpl
6
+
7
+ # Authenticates requests made to the GlobalCollect platform using the HMAC algorithm.
8
+ class DefaultAuthenticator < Authenticator
9
+ # HMAC algorithm used to generate the signature
10
+ HMAC_ALGOR = 'SHA256'
11
+ CONTENT_TYPE = 'Content-Type'
12
+ DATE = 'Date'
13
+ XGCS = 'x-gcs'
14
+
15
+ # Construct a new DefaultAuthenticator instance that can sign requests
16
+ # with the provided _api_key_id_ and _secret_api_key_.
17
+ # authorization_type:: The authorization protocol to use for authentication.
18
+ # api_key_id:: Identifier for the secret key used in authentication.
19
+ # secret_api_key:: The secret key that is used to generate the authentication signature.
20
+ def initialize(authorization_type, api_key_id, secret_api_key)
21
+ raise ArgumentError unless authorization_type
22
+ raise ArgumentError unless api_key_id and not api_key_id.strip.empty?
23
+ raise ArgumentError unless secret_api_key and not secret_api_key.strip.empty?
24
+
25
+ @authorization_type = authorization_type
26
+ @api_key_id = api_key_id
27
+ @secret_api_key = secret_api_key
28
+ end
29
+
30
+ # Creates a signature to authenticate a request.
31
+ # Uses the following parameters:
32
+ # http_method:: 'GET', 'PUT', 'POST' or 'DELETE' indicating which HTTP method will be used with the request
33
+ # resource_uri:: URI object that includes #path and #query of the url that will be used, #query may be *nil*
34
+ # request_headers:: {Ingenico::Connect::SDK::RequestHeader} list that contains all headers used by the request
35
+ def create_simple_authentication_signature(http_method, resource_uri, http_headers)
36
+ raise ArgumentError unless http_method and not http_method.strip.empty?
37
+ raise ArgumentError unless resource_uri
38
+
39
+ data_to_sign = to_data_to_sign(http_method, resource_uri, http_headers)
40
+ "GCS #{@authorization_type}:#{@api_key_id}:#{create_auth_signature(data_to_sign)}"
41
+ end
42
+
43
+ protected
44
+
45
+ # Canonizes the _http_method_, _resource_uri_ and _http_headers_ so a unique signature can be generated.
46
+ # Canonical form is as follows:
47
+ # * _http_method_ in upper case
48
+ # * Content-Type
49
+ # * Date header
50
+ # * X-GCS headers sorted alphabetically. Names are in lowercase and values are stripped of excess whitespace
51
+ # * path and query portion of the uri, separated by a question mark
52
+ def to_data_to_sign(http_method, resource_uri, http_headers)
53
+ content_type = ''
54
+ date = ''
55
+ canonical_resource = to_canonical_resource(resource_uri)
56
+ xgc_http_headers = []
57
+
58
+ http_headers.each do |header|
59
+ name, value = header.name, header.value
60
+ case
61
+ when name.casecmp(CONTENT_TYPE) == 0
62
+ content_type = value
63
+ when name.casecmp(DATE) == 0
64
+ date = value
65
+ when to_canonical_header_name(name).start_with?(XGCS)
66
+ xgc_http_headers << [ to_canonical_header_name(name), to_canonical_header_value(value) ]
67
+ end
68
+ end if http_headers
69
+
70
+ xgc_http_headers.sort! { |(h1, v1), (h2, v2)| h1 <=> h2 } unless xgc_http_headers.empty?
71
+
72
+ data = http_method.upcase + "\n" +
73
+ content_type + "\n" + date + "\n"
74
+ data += xgc_http_headers.inject('') { |s, (k, v)| s + k + ':' + v + "\n" } unless xgc_http_headers.empty?
75
+ data += canonical_resource + "\n" unless canonical_resource.nil?
76
+ data
77
+ end
78
+
79
+ # Applies the HMAC algorithm to the canonicalized data to obtain an HMAC digest.
80
+ # Afterwards the HMAC digest is encoded using base64 encoding.
81
+ def create_auth_signature(data_to_sign)
82
+ digest = OpenSSL::Digest.new(HMAC_ALGOR)
83
+ hmac = OpenSSL::HMAC.digest(digest, @secret_api_key, data_to_sign)
84
+ Base64.strict_encode64(hmac).strip
85
+ end
86
+
87
+ private
88
+
89
+ # Returns the encoded URI path without the HTTP method and including all decoded query parameters.
90
+ def to_canonical_resource(resource_uri)
91
+ return resource_uri.path + '?' + resource_uri.query if resource_uri.query
92
+ return resource_uri.path
93
+ end
94
+
95
+ def to_canonical_header_name(original_name)
96
+ original_name ? original_name.downcase : original_name
97
+ end
98
+
99
+ # Strips a header value of excess whitespace to produce a canonical value
100
+ def to_canonical_header_value(original_value)
101
+ return '' unless original_value
102
+ original_value.gsub(/\r?\n[\s&&[^\r\n]]*/, ' ').strip
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,242 @@
1
+ require 'securerandom'
2
+ require 'uri'
3
+ require 'httpclient'
4
+
5
+ # @private :nodoc: this is not our class
6
+ class HTTPClient
7
+ # (monkey) patch to gain access to the session pool size in HTTPClient
8
+ def session_count
9
+ sess_pool = @session_manager.instance_variable_get(:@sess_pool)
10
+ sess_pool.size
11
+ end
12
+ end
13
+
14
+ module Ingenico::Connect::SDK
15
+ module DefaultImpl
16
+
17
+ class DefaultConnection < PooledConnection
18
+
19
+ CONTENT_TYPE = 'Content-Type'
20
+ JSON_CONTENT_TYPE = 'application/json'
21
+
22
+ # Initialized using a hash containing the following parameters:
23
+ # connect_timeout:: Connection timeout in seconds.
24
+ # socket_timeout:: Socket timeout in seconds.
25
+ # max_connections:: Number of connections kept alive in the thread pool.
26
+ # Uses {Ingenico::Connect::SDK::CommunicatorConfiguration.DEFAULT_MAX_CONNECTIONS} if not given.
27
+ # proxy_configuration:: {Ingenico::Connect::SDK::ProxyConfiguration} object that stores the proxy to use.
28
+ # If not given the system default proxy is used;
29
+ # if there is no system default proxy set either, no proxy is used.
30
+ def initialize(args)
31
+ raise ArgumentError unless args.is_a? Hash
32
+ # Set timeouts to nil if they are negative
33
+ @connect_timeout = args[:connect_timeout]
34
+ @connect_timeout = nil unless @connect_timeout.nil? || @connect_timeout > 0
35
+ @socket_timeout = args[:socket_timeout]
36
+ @socket_timeout = nil unless @socket_timeout.nil? || @socket_timeout > 0
37
+ @max_connections = args[:max_connections] || CommunicatorConfiguration.DEFAULT_MAX_CONNECTIONS
38
+ @proxy_configuration = args[:proxy_configuration]
39
+
40
+ # HTTPClient provides the following features:
41
+ # 1) thread safe, an instance can be used by multiple threads without
42
+ # explicit synchronization
43
+ # 2) use persistent connection if HTTP 1.1 is supported. The connection
44
+ # will be left open until explicitly closed or keep_alive_timeout
45
+ # 3) a built-in connection pool with no limit for max connections
46
+ @http_client = create_http_client
47
+ @http_client.connect_timeout = @connect_timeout
48
+ @http_client.send_timeout = @socket_timeout
49
+ @http_client.receive_timeout = @socket_timeout
50
+ end
51
+
52
+ private
53
+
54
+ # Create a HTTPClient instance that uses @proxy_configuration or the system proxy if @proxy_configuration is not set
55
+ def create_http_client
56
+ if @proxy_configuration
57
+ httpclient = HTTPClient.new(@proxy_configuration.proxy_uri)
58
+ httpclient.set_proxy_auth(@proxy_configuration.username, @proxy_configuration.password)
59
+ httpclient
60
+ else # use system settings
61
+ proxy_string = ENV['https_proxy'] || ENV['http_proxy']
62
+ # proxy string format = 'http://username:password@hostname:port'
63
+ proxy_string =~ %r(https?//(?<username>[^:]):(?<password>[^@])@.*)
64
+ username = $1
65
+ password = $2
66
+ httpclient = HTTPClient.new(proxy_string)
67
+ httpclient.set_proxy_auth(username, password) unless username.nil? || password.nil?
68
+ httpclient
69
+ end
70
+ end
71
+
72
+ public
73
+
74
+ # Closes all connections idle for longer than _idle_time_ seconds.
75
+ # In addition, the keep_alive_timeout is set to _idle_time_
76
+ # so any future connections idle for longer than _idle_time_ seconds will also be closed.
77
+ def close_idle_connections(idle_time) # in sec
78
+ @http_client.keep_alive_timeout = idle_time # set timeout value
79
+ close_expired_connections
80
+ end
81
+
82
+ # HTTPClient automatically closes expired connections so _close_expired_connections_ is a no-operation.
83
+ def close_expired_connections
84
+ # By default the keep alive timeout is 15 sec, which is the HTTP 1.1
85
+ # standard. To change the value, use keep_alive_timeout= method
86
+ # do nothing, handled by HTTPClient
87
+ end
88
+
89
+ # Frees all networking resources used.
90
+ def close
91
+ @http_client.reset_all
92
+ end
93
+
94
+ # Returns the number of open connections
95
+ def session_count
96
+ @http_client.session_count
97
+ end
98
+
99
+ # Performs a GET request to the GlobalCollect platform
100
+ # @see request
101
+ def get(uri, request_headers)
102
+ request('get', uri, request_headers)
103
+ end
104
+
105
+ # Performs a DELETE request to the GlobalCollect platform
106
+ # @see request
107
+ def delete(uri, request_headers)
108
+ request('delete', uri, request_headers)
109
+ end
110
+
111
+ # Performs a POST request to the GlobalCollect platform
112
+ # @see request
113
+ def post(uri, request_headers, body)
114
+ request('post', uri, request_headers, body)
115
+ end
116
+
117
+ # Performs a PUT request to the GlobalCollect platform
118
+ # @see request
119
+ def put(uri, request_headers, body)
120
+ request('put', uri, request_headers, body)
121
+ end
122
+
123
+ # performs a HTTP request and returns the response as an {Ingenico::Connect::SDK::Response} object.
124
+ # Also ensures the request is logged when sent and its response is logged when received.
125
+ # Raises {Ingenico::Connect::SDK::CommunicationException} when communication with the GlobalCollect platform was not successful.
126
+ # method:: 'GET', 'DELETE', 'POST' or 'PUT' depending on the HTTP method being used.
127
+ # uri:: Full URI of the location the request is targeted at, including query parameters.
128
+ # request_headers:: {Ingenico::Connect::SDK::RequestHeader} list of headers that should be used as HTTP headers in the request.
129
+ # body:: Request body as a String.
130
+ def request(method, uri, request_headers, body=nil)
131
+ request_headers = convert_from_sdk_headers(request_headers)
132
+ request_id = SecureRandom.uuid
133
+ request_headers[CONTENT_TYPE] = JSON_CONTENT_TYPE if body
134
+ content_type = request_headers[CONTENT_TYPE]
135
+ info = { headers: request_headers, content_type: content_type }
136
+ info[:body] = body unless body.nil?
137
+ log_request(request_id, method.upcase, uri, info)
138
+
139
+ start_time = Time.now
140
+ begin
141
+ response = if body
142
+ @http_client.send(method, uri, header: request_headers, body: body)
143
+ else
144
+ @http_client.send(method, uri, header: request_headers)
145
+ end
146
+ rescue HTTPClient::TimeoutError => e
147
+ log_error(request_id, start_time, e)
148
+ raise Ingenico::Connect::SDK::CommunicationException.new(e)
149
+ rescue HTTPClient::KeepAliveDisconnected, HTTPClient::RetryableResponse => e # retry these?
150
+ log_error(request_id, start_time, e)
151
+ raise Ingenico::Connect::SDK::CommunicationException.new(e)
152
+ rescue => e
153
+ log_error(request_id, start_time, e)
154
+ raise Ingenico::Connect::SDK::CommunicationException.new(e)
155
+ end
156
+
157
+ log_response(request_id, response.status, start_time,
158
+ headers: response.headers, body: response.body,
159
+ content_type: response.content_type)
160
+ convert_to_sdk_response(response)
161
+ end
162
+
163
+ # logging code
164
+
165
+ # Enables logging outgoing requests and incoming responses by registering the _communicator_logger_.
166
+ # Note that only one logger can be registered at a time and calling _enable_logging_
167
+ # a second time will override the old logger instance with the new one.
168
+ #
169
+ # communicator_logger:: The {Ingenico::Connect::SDK::Logging::CommunicatorLogger} the requests and responses are logged to
170
+ #
171
+ def enable_logging(communicator_logger)
172
+ raise ArgumentError.new('communicatorLogger is required') unless communicator_logger
173
+ @communicator_logger = communicator_logger
174
+ end
175
+
176
+ # Disables logging by unregistering any previous logger that might be registered.
177
+ def disable_logging
178
+ @communicator_logger = nil
179
+ end
180
+
181
+ private
182
+
183
+ # Converts a {Ingenico::Connect::SDK::RequestHeader} list headers to a hash
184
+ def convert_from_sdk_headers(headers)
185
+ hash = {}
186
+ headers.each { |h| hash[h.name] = h.value }
187
+ hash
188
+ end
189
+
190
+ # Converts a hash to a {Ingenico::Connect::SDK::ResponseHeader} list
191
+ def convert_to_sdk_headers(headers)
192
+ arr = []
193
+ headers.each { |k, v| arr << Ingenico::Connect::SDK::ResponseHeader.new(k, v) }
194
+ arr
195
+ end
196
+
197
+ # converts a HTTPClient response to a {Ingenico::Connect::SDK::Response}
198
+ def convert_to_sdk_response(response)
199
+ Ingenico::Connect::SDK::Response.new(response.status,
200
+ response.body,
201
+ convert_to_sdk_headers(response.headers))
202
+ end
203
+
204
+ def log_request(requestId, method, uri, args={})
205
+ return unless @communicator_logger
206
+
207
+ headers, body, content_type = args[:headers], args[:body], args[:content_type]
208
+ log_msg_builder = Ingenico::Connect::SDK::Logging::RequestLogMessageBuilder.new(requestId, method, uri)
209
+ headers.each { |k, v| log_msg_builder.add_headers(k, v) } if headers
210
+ log_msg_builder.set_body(body, content_type)
211
+
212
+ begin
213
+ @communicator_logger.log(log_msg_builder.get_message)
214
+ rescue => e
215
+ @communicator_logger.log("An error occurred trying to log request #{requestId}", e)
216
+ end
217
+ end
218
+
219
+ def log_response(requestId, status_code, start_time, args={})
220
+ return unless @communicator_logger
221
+
222
+ duration = (Time.now - start_time) * 1000 # in millisecs
223
+ headers, body, content_type = args[:headers], args[:body], args[:content_type]
224
+ log_msg_builder = Ingenico::Connect::SDK::Logging::ResponseLogMessageBuilder.new(requestId, status_code, duration)
225
+ headers.each { |k, v| log_msg_builder.add_headers(k, v) } if headers
226
+ log_msg_builder.set_body(body, content_type)
227
+
228
+ begin
229
+ @communicator_logger.log(log_msg_builder.get_message)
230
+ rescue => e
231
+ @communicator_logger.log("An error occurred trying to log response #{requestId}", e)
232
+ end
233
+ end
234
+
235
+ def log_error(requestId, start_time, thrown)
236
+ return unless @communicator_logger
237
+ duration = (Time.now - start_time) * 1000 # in millisecs
238
+ @communicator_logger.log("Error occurred for outgoing request (requestId='#{requestId}', #{duration} ms)", thrown)
239
+ end
240
+ end
241
+ end
242
+ end