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,8 @@
1
+ prefix = 'ingenico/connect/sdk/'
2
+ suffix = '_exception'
3
+ exception_types = %w[api authorization communication declined_transaction
4
+ declined_payment declined_payout declined_refund
5
+ global_collect idempotence marshaller_syntax not_found
6
+ reference response validation]
7
+
8
+ exception_types.each { |type| require prefix + type + suffix }
@@ -0,0 +1,200 @@
1
+ require 'yaml'
2
+
3
+ module Ingenico::Connect::SDK
4
+
5
+ # Convenience class that constructs instances of several other classes in the SDK.
6
+ # Provides methods to construct
7
+ # {Ingenico::Connect::SDK::CommunicatorConfiguration}, {Ingenico::Connect::SDK::Session}, {Ingenico::Connect::SDK::Communicator} and {Ingenico::Connect::SDK::Client} instances.
8
+ class Factory
9
+
10
+ # Creates and returns a {Ingenico::Connect::SDK::CommunicatorConfiguration} based on the configuration in the file
11
+ # located at _configuration_file_name_.
12
+ #
13
+ # configuration_file_name:: Path to the configuration file to use, should be in YAML format.
14
+ # api_key_id:: Key id for the GlobalCollect service.
15
+ # secret_api_key:: Secret key used for authentication to the GlobalCollect service.
16
+ def self.create_configuration(configuration_file_name, api_key_id, secret_api_key)
17
+ properties = YAML::load_file(configuration_file_name)
18
+ CommunicatorConfiguration.new(properties: properties,
19
+ api_key_id: api_key_id,
20
+ secret_api_key: secret_api_key)
21
+ end
22
+
23
+ # Creates and returns a {Ingenico::Connect::SDK::Session} from an {Ingenico::Connect::SDK::CommunicatorConfiguration}, an {Ingenico::Connect::SDK::MetaDataProvider},
24
+ # an {Ingenico::Connect::SDK::Connection} and an {Ingenico::Connect::SDK::Authenticator}.
25
+ # If an authenticator is not given, a {Ingenico::Connect::SDK::DefaultImpl::DefaultAuthenticator} is created
26
+ # using the _api_key_id_ and _secret_api_key_ in the CommunicatorConfiguration.
27
+ #
28
+ # configuration:: {Ingenico::Connect::SDK::CommunicatorConfiguration} that contains configuration settings
29
+ # to be used by the client.
30
+ # meta_data_provider:: {Ingenico::Connect::SDK::MetaDataProvider} that stores the metadata for the communicating client.
31
+ # connection:: Implementation of {Ingenico::Connect::SDK::Connection} that can be used to communicate
32
+ # with the GlobalCollect Platform.
33
+ # authenticator:: Implementation of {Ingenico::Connect::SDK::Authenticator} that can authenticate messages
34
+ # sent to the GlobalCollect platform.
35
+ def self.create_session_from_configuration(configuration, meta_data_provider: nil,
36
+ connection: nil, authenticator: nil)
37
+ unless meta_data_provider
38
+ meta_data_provider = MetaDataProvider.new(configuration.integrator,
39
+ shopping_cart_extension: configuration.shopping_cart_extension)
40
+ end
41
+ unless connection
42
+ connection = DefaultImpl::DefaultConnection.new({connect_timeout: configuration.connect_timeout,
43
+ socket_timeout: configuration.socket_timeout,
44
+ max_connections: configuration.max_connections,
45
+ proxy_configuration: configuration.proxy_configuration})
46
+ end
47
+ unless authenticator
48
+ authenticator = DefaultImpl::DefaultAuthenticator.new(configuration.authorization_type,
49
+ configuration.api_key_id, configuration.secret_api_key)
50
+ end
51
+ Session.new(configuration.api_endpoint, connection, authenticator, meta_data_provider)
52
+ end
53
+
54
+ # Creates and returns a {Ingenico::Connect::SDK::Session} from a file containing the communicator configuration, api_key_id, secret_api_key,
55
+ # an {Ingenico::Connect::SDK::MetaDataProvider}, an {Ingenico::Connect::SDK::Connection} and an {Ingenico::Connect::SDK::Authenticator}.
56
+ # If an authenticator is not given, a {Ingenico::Connect::SDK::DefaultImpl::DefaultAuthenticator} is created
57
+ # using the _api_key_id_ and _secret_api_key_ in the CommunicatorConfiguration.
58
+ #
59
+ # configuration_file_name:: Path to the configuration file to use, should be in YAML format.
60
+ # api_key_id:: Key id for the GlobalCollect service.
61
+ # secret_api_key:: Secret key used for authentication to the GlobalCollect service.
62
+ # meta_data_provider:: {Ingenico::Connect::SDK::MetaDataProvider} that stores the metadata for the communicating client.
63
+ # connection:: Implementation of {Ingenico::Connect::SDK::Connection} that can be used to communicate
64
+ # with the GlobalCollect Platform.
65
+ # authenticator:: Implementation of {Ingenico::Connect::SDK::Authenticator} that can authenticate messages
66
+ # sent to the GlobalCollect platform.
67
+ def self.create_session_from_file(configuration_file_name, api_key_id, secret_api_key,
68
+ meta_data_provider: nil, connection: nil, authenticator: nil)
69
+ configuration = create_configuration(configuration_file_name, api_key_id, secret_api_key)
70
+ create_session_from_configuration(configuration, meta_data_provider: meta_data_provider, connection: connection,
71
+ authenticator: authenticator)
72
+ end
73
+
74
+ # Creates and returns an {Ingenico::Connect::SDK::Communicator} that is used for communication with the GlobalCollect service.
75
+ #
76
+ # session:: {Ingenico::Connect::SDK::Session} that the communicator will utilize for communication.
77
+ def self.create_communicator_from_session(session)
78
+ Communicator.new(session, DefaultImpl::DefaultMarshaller.INSTANCE)
79
+ end
80
+
81
+ # Creates and returns an {Ingenico::Connect::SDK::Communicator} that can be used for communication with the GlobalCollect service.
82
+ #
83
+ # configuration:: {Ingenico::Connect::SDK::CommunicatorConfiguration} that contains configuration settings
84
+ # to be used by the client.
85
+ def self.create_communicator_from_configuration(configuration)
86
+ session = create_session_from_configuration(configuration)
87
+ Communicator.new(session, DefaultImpl::DefaultMarshaller.INSTANCE)
88
+ end
89
+
90
+ # Creates and returns an {Ingenico::Connect::SDK::Communicator} that is used for communication with the GlobalCollect service.
91
+ #
92
+ # configuration_file_name:: Path to the configuration file to use, should be in YAML format.
93
+ # api_key_id:: Key id for the GlobalCollect service.
94
+ # secret_api_key:: Secret key used for authentication to the GlobalCollect service.
95
+ def self.create_communicator_from_file(configuration_file_name, api_key_id, secret_api_key)
96
+ configuration = create_configuration(configuration_file_name, api_key_id, secret_api_key)
97
+ session = create_session_from_configuration(configuration)
98
+ Communicator.new(session, DefaultImpl::DefaultMarshaller.INSTANCE)
99
+ end
100
+
101
+ # Creates and returns an {Ingenico::Connect::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
102
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
103
+ #
104
+ # @example Providing a code block
105
+ # Factory.create_client_from_configuration(configuration) do |client|
106
+ # client.merchant(merchant_id).services.testconnection
107
+ # end
108
+ # # client is closed here
109
+ #
110
+ # configuration:: {Ingenico::Connect::SDK::CommunicatorConfiguration} that contains configuration settings
111
+ # to be used by the client.
112
+ def self.create_client_from_configuration(configuration)
113
+ communicator = create_communicator_from_configuration(configuration)
114
+ client = Client.new(communicator)
115
+ if block_given?
116
+ begin
117
+ yield client
118
+ ensure
119
+ client.close
120
+ end
121
+ else
122
+ return client
123
+ end
124
+ end
125
+
126
+ # Creates and returns an {Ingenico::Connect::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
127
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
128
+ #
129
+ # @example Providing a code block
130
+ # Factory.create_client_from_communicator(communicator) do |client|
131
+ # client.merchant(merchant_id).services.testconnection
132
+ # end
133
+ # # client is closed here
134
+ #
135
+ # communicator:: {Ingenico::Connect::SDK::Communicator} that provides network communication service for the Client
136
+ def self.create_client_from_communicator(communicator)
137
+ client = Client.new(communicator)
138
+ if block_given?
139
+ begin
140
+ yield client
141
+ ensure
142
+ client.close
143
+ end
144
+ else
145
+ return client
146
+ end
147
+ end
148
+
149
+ # Creates and returns an {Ingenico::Connect::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
150
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
151
+ #
152
+ # @example Providing a code block
153
+ # Factory.create_client_from_session(session) do |client|
154
+ # client.merchant(merchant_id).services.testconnection
155
+ # end
156
+ # # client is closed here
157
+ #
158
+ # session:: {Ingenico::Connect::SDK::Session} that the Client will utilize for communication.
159
+ def self.create_client_from_session(session)
160
+ communicator = create_communicator_from_session(session)
161
+ client = Client.new(communicator)
162
+ if block_given?
163
+ begin
164
+ yield client
165
+ ensure
166
+ client.close
167
+ end
168
+ else
169
+ return client
170
+ end
171
+ end
172
+
173
+ # Creates and returns an {Ingenico::Connect::SDK::Client} that provides the a high-level interface with the GlobalCollect service.
174
+ # If a code block is given, the created client is returned to the code block and closed afterwards.
175
+ #
176
+ # @example Providing a code block
177
+ # Factory.create_client_from_file(configuration_file_name, api_key_id, secret_api_key) do |client|
178
+ # client.merchant(merchant_id).services.testconnection
179
+ # end
180
+ # # client is closed here
181
+ #
182
+ # configuration_file_name:: Path to the configuration file to use for configuring the Client,
183
+ # should be in YAML format.
184
+ # api_key_id:: Key id for the GlobalCollect service.
185
+ # secret_api_key:: Secret key used for authentication to the GlobalCollect service.
186
+ def self.create_client_from_file(configuration_file_name, api_key_id, secret_api_key)
187
+ communicator = create_communicator_from_file(configuration_file_name, api_key_id, secret_api_key)
188
+ client = Client.new(communicator)
189
+ if block_given?
190
+ begin
191
+ yield client
192
+ ensure
193
+ client.close
194
+ end
195
+ else
196
+ return client
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,15 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # This exception is thrown when a response from the GlobalCollect platform indicates that an error occurred
4
+ # on the GlobalCollect platform while processing the request.
5
+ # This corresponds to a HTTP status code of 500 or 502.
6
+ class GlobalCollectException < ApiException
7
+
8
+ # Create a new GlobalCollectException
9
+ # @see ApiException#initialize
10
+ def initialize(status_code, response_body, error_id, errors,
11
+ message='the GlobalCollect platform returned an error response')
12
+ super(status_code, response_body, error_id, errors, message)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Ingenico::Connect::SDK
2
+
3
+ # This exception is thrown when a response from the GlobalCollect platform indicates
4
+ # a request with the same _idempotence_key_ was received earlier.
5
+ # The _idempotence_request_timestamp_ indicates the time when the first request with this _idempotence_key_ arrived.
6
+ class IdempotenceException < ApiException
7
+
8
+ # Create a new IdempotenceException
9
+ # @see ApiException#initialize
10
+ def initialize(status_code, response_body, error_id, errors, idempotence_key,
11
+ idempotence_request_timestamp,
12
+ message='the GlobalCollect platform returned a duplicate request error response')
13
+ super(status_code, response_body, error_id, errors, message)
14
+ @idempotence_key = idempotence_key
15
+ @idempotence_request_timestamp = idempotence_request_timestamp
16
+ end
17
+
18
+ # The idempotence key used in the request.
19
+ attr_reader :idempotence_key
20
+
21
+ # A timestamp indicating the arrival time of the request that conflicts with the request just sent.
22
+ attr_reader :idempotence_request_timestamp
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ prefix = 'ingenico/connect/sdk/logging/'
2
+
3
+ require prefix + 'logging_capable'
4
+ require prefix + 'log_message_builder'
5
+ require prefix + 'request_log_message_builder'
6
+ require prefix + 'response_log_message_builder'
7
+ require prefix + 'logging_util'
8
+ require prefix + 'communicator_logger'
9
+ require prefix + 'ruby_communicator_logger'
10
+ require prefix + 'stdout_communicator_logger'
@@ -0,0 +1,19 @@
1
+ module Ingenico::Connect::SDK
2
+ module Logging
3
+
4
+ # Base logger class used in this SDK. This class is an interface and cannot be instantiated.
5
+ class CommunicatorLogger
6
+ # interface, no instantiation
7
+ # @see Ingenico::Connect::SDK::Logging::StdoutCommunicatorLogger
8
+ # @see Ingenico::Connect::SDK::Logging::RubyCommunicatorLogger
9
+ def initialize
10
+ raise NotImplementedError("#{self.class.name} is not implemented.")
11
+ end
12
+
13
+ # logs a message with or without exception
14
+ def log(message, thrown=false)
15
+ raise NotImplementedError("#{self.class.name}#log() is not implemented.")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,61 @@
1
+ module Ingenico::Connect::SDK
2
+ module Logging
3
+
4
+ # Abstract class used to construct a message describing a request or response.
5
+ class LogMessageBuilder
6
+
7
+ # An identifier assigned to the request and response
8
+ attr_reader :request_id
9
+
10
+ # Request or response headers in string form
11
+ attr_reader :headers
12
+
13
+ # Request or response body as a string
14
+ attr_reader :body
15
+
16
+ # Content type of the body, generally 'application/json' or 'text/html'
17
+ attr_reader :content_type
18
+
19
+ # Create a new LogMessageBuilder
20
+ def initialize(requestId)
21
+ raise ArgumentError if requestId.nil? or requestId.empty?
22
+ @request_id = requestId
23
+ @headers = ''
24
+ end
25
+
26
+ # Adds a single header to the #headers string
27
+ def add_headers(name, value)
28
+ @headers += ', ' if @headers.length > 0
29
+ @headers += name + '="'
30
+ @headers += LoggingUtil.obfuscate_header(name, value) unless value.nil?
31
+ @headers += '"'
32
+ end
33
+
34
+ # Sets the body of this message to the parameter body.
35
+ # body:: The message body
36
+ # content_type:: The content type of the body
37
+ def set_body(body, content_type)
38
+ @body = LoggingUtil.obfuscate_body(body)
39
+ @content_type = content_type
40
+ end
41
+
42
+ # Constructs and returns the log message as a string.
43
+ def get_message
44
+ raise NotImplementedError("#{self.class.name}#get_message() is not implemented.")
45
+ end
46
+
47
+ def to_s
48
+ if self.class == LogMessageBuilder
49
+ return super.to_s
50
+ else
51
+ return get_message
52
+ end
53
+ end
54
+
55
+ # Returns an empty string if the parameter is nil, and returns the parameter itself otherwise
56
+ protected def empty_if_null(value)
57
+ value.nil? ? '' : value
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,19 @@
1
+ module Ingenico
2
+ module Connect
3
+ module SDK
4
+ module Logging
5
+
6
+ # Abstract mixin module that allows loggers to be registered to an object.
7
+ module LoggingCapable
8
+ def enable_logging(communicator_logger)
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def disable_logging
13
+ raise NotImplementedError
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,298 @@
1
+ module Ingenico::Connect::SDK
2
+ module Logging
3
+
4
+ # Class responsible for obfuscating sensitive data in a message body.
5
+ class ValueObfuscator
6
+
7
+ private
8
+
9
+ # Creates a new ValueObfuscator.
10
+ # fixed_length:: If greater than 0, all values that will be obfuscated
11
+ # will be replaced with that number of asterisks.
12
+ # keep_start_count:: The number of characters to not obfuscate at the end of any value.
13
+ # This parameter is only used if _fixed_length_ = 0.
14
+ # keep_end_count:: The number of characters to not obfuscate at the start of any value.
15
+ # This parameter is only used if _fixed_length_ = 0.
16
+ def initialize(fixed_length, keep_start_count, keep_end_count)
17
+ @mask_character = '*'
18
+ @fixed_length = fixed_length
19
+ @keep_start_count = keep_start_count
20
+ @keep_end_count = keep_end_count
21
+ end
22
+
23
+ public
24
+
25
+ @@ALL = ValueObfuscator.new(0, 0, 0)
26
+
27
+ def self.ALL
28
+ @@ALL
29
+ end
30
+
31
+ # Creates a new ValueObfuscator that replaces any sensitive data with a _fixed_length_ line of asterisks.
32
+ def self.fixed_length(fixed_length)
33
+ ValueObfuscator.new(fixed_length, 0, 0)
34
+ end
35
+
36
+ # Creates a new ValueObfuscator that retains only the first _count_ characters of any value to obfuscate
37
+ # and replaces the rest with asterisks.
38
+ def self.keep_start_count(count)
39
+ ValueObfuscator.new(0, count, 0)
40
+ end
41
+
42
+ # Creates a new ValueObfuscator that retains only the last _count_ characters of any value to obfuscate
43
+ # and replaces the rest with asterisks.
44
+ def self.keep_end_count(count)
45
+ ValueObfuscator.new(0, 0, count)
46
+ end
47
+
48
+ # Obfuscates the parameter value.
49
+ def obfuscate_value(value)
50
+ return value if value.nil? or value.empty?
51
+ return repeat_mask(@fixed_length) if @fixed_length > 0
52
+ return repeat_mask(value.length) if @keep_start_count == 0 and @keep_end_count == 0
53
+ return value if value.length < (@keep_start_count + @keep_end_count)
54
+
55
+ # range describes the range of characters to replace with asterisks
56
+ range = @keep_start_count...(value.length - @keep_end_count)
57
+ value[range] = @mask_character * range.size
58
+ value
59
+ end
60
+
61
+ private
62
+
63
+ def repeat_mask(count)
64
+ @mask_character * count
65
+ end
66
+ end # end of ValueObfuscator
67
+
68
+ class Obfuscator
69
+ def initialize(obfuscators, case_insensitive)
70
+ raise ArgumentError unless obfuscators.is_a? Hash
71
+ @obfuscators = copy(obfuscators, case_insensitive)
72
+ end
73
+
74
+ private
75
+
76
+ # case insensitive hash
77
+ # @private
78
+ class HashClod < Hash
79
+
80
+ def initialize(other)
81
+ other.each { |k, v| self.[]=(k, v) }
82
+ end
83
+
84
+ def [](key)
85
+ super _insensitive(key)
86
+ end
87
+
88
+ def []=(key, value)
89
+ super _insensitive(key), value
90
+ end
91
+
92
+ protected
93
+
94
+ def _insensitive(key)
95
+ key.respond_to?(:upcase) ? key.upcase : key
96
+ end
97
+ end # end of HashClod
98
+
99
+ def copy(obfuscators, case_insensitive)
100
+ cp = case_insensitive ? HashClod.new(obfuscators) : obfuscators
101
+ Marshal.load(Marshal.dump(cp)) # deep copy
102
+ end
103
+
104
+ public
105
+
106
+ def obfuscate_value(key, value)
107
+ obfuscator = @obfuscators[key]
108
+ obfuscator.nil? ? value : obfuscator.obfuscate_value(value)
109
+ end
110
+
111
+ # A convenient wrapper to build obfuscators
112
+ class Builder
113
+ attr_accessor :obfuscators
114
+
115
+ def initialize
116
+ raise NotImplementedError.new("#{self.class.name} is not implemented.")
117
+ end
118
+
119
+ def with_all(key)
120
+ @obfuscators[key] = ValueObfuscator.ALL
121
+ self
122
+ end
123
+
124
+ def with_fixed_length(key, fixed_length)
125
+ @obfuscators[key] = ValueObfuscator.fixed_length(fixed_length)
126
+ self
127
+ end
128
+
129
+ def with_keep_start_count(key, count)
130
+ @obfuscators[key] = ValueObfuscator.keep_start_count(count)
131
+ self
132
+ end
133
+
134
+ def with_keep_end_count(key, count)
135
+ @obfuscators[key] = ValueObfuscator.keep_end_count(count)
136
+ self
137
+ end
138
+
139
+ def build
140
+ raise NotImplementedError.new("#{self.class.name}#build() is not implemented.")
141
+ end
142
+ end # Builder
143
+ end # Obfuscator
144
+
145
+ # Class that obfuscates headers of a message
146
+ class HeaderObfuscator < Obfuscator
147
+ def initialize(obfuscators)
148
+ # case insensitive
149
+ super(obfuscators, true)
150
+ end
151
+
152
+ def self.builder
153
+ Builder.new
154
+ end
155
+
156
+ class Builder < Obfuscator::Builder
157
+ def initialize
158
+ @obfuscators = {}
159
+ end
160
+
161
+ def with_all(name)
162
+ raise ArgumentError unless name.is_a? String
163
+ super(name)
164
+ end
165
+
166
+ def with_fixed_length(name, fixedLength)
167
+ raise ArgumentError unless name.is_a? String
168
+ super(name, fixedLength)
169
+ end
170
+
171
+ # with_keep_start_count and with_keep_end_count are the same
172
+ # no need to override
173
+
174
+ def build
175
+ HeaderObfuscator.new(obfuscators)
176
+ end
177
+ end
178
+ end # end of HeadObfuscator
179
+
180
+ # Class that obfuscates properties in the JSON body of a message
181
+ class PropertyObfuscator < Obfuscator
182
+ def initialize(obfuscators)
183
+ # case sensitive
184
+ super(obfuscators, false)
185
+ @propertyPattern = build_property_pattern(obfuscators.keys)
186
+ end
187
+
188
+ private
189
+
190
+ def build_property_pattern(pn)
191
+ return /$^/ if pn.empty? # no possible match
192
+ # Regex to create:
193
+ # (["'])(X|Y|Z)\1\s*:\s*(?:(["'])(.*?)(?<!\\)\3|([^"'\s]\S*))
194
+ # Groups:
195
+ # 1: opening " or ' for the property name
196
+ # 2: property name
197
+ # 3: opening " or ' for the value
198
+ # 4: quoted value
199
+ # 5: non-quoted-value
200
+ # The negative lookbehind is to allow escaped quotes to be part of
201
+ # the value. What this does not allow currently is having values end
202
+ # with a \ (which would be escaped to \\).
203
+ regex = pn.inject("([\"'])(") { |r, p| r += Regexp.quote(p) + '|'}.chop +
204
+ ")\\1\\s*:\\s*(?:([\"'])(.*?)(?<!\\\\)\\3|([^\"'\\s]\\S*))"
205
+ /#{regex}/m # dotall mode
206
+ end
207
+
208
+ public
209
+
210
+ def obfuscate(body)
211
+ return nil if body.nil?
212
+ return '' if body.empty?
213
+
214
+ body.gsub(@propertyPattern) do
215
+ m = Regexp.last_match
216
+ propertyName = m[2]
217
+ value = m[4] || m[5]
218
+ # copy value 'cause it's part of m[0]
219
+ m[0].sub(value, obfuscate_value(propertyName, value.dup))
220
+ end
221
+ end
222
+
223
+ def self.builder
224
+ Builder.new
225
+ end
226
+
227
+ class Builder < Obfuscator::Builder
228
+ def initialize
229
+ # implement the class
230
+ @obfuscators = {}
231
+ end
232
+
233
+ def with_all(property)
234
+ raise ArgumentError unless property.is_a? String
235
+ super(property)
236
+ end
237
+
238
+ def with_fixed_length(property, fixedLength)
239
+ raise ArgumentError unless property.is_a? String
240
+ super(property, fixedLength)
241
+ end
242
+
243
+ def with_keep_start_count(key, count)
244
+ raise ArgumentError unless key.is_a? String
245
+ super(key, count)
246
+ end
247
+
248
+ def with_keep_end_count(property, count)
249
+ raise ArgumentError unless property.is_a? String
250
+ super(property, count)
251
+ end
252
+
253
+ def build
254
+ PropertyObfuscator.new(obfuscators)
255
+ end
256
+ end
257
+ end # end of property obfuscator
258
+
259
+ class LoggingUtil
260
+ @@PROPERTY_OBFUSCATOR = PropertyObfuscator.builder
261
+ .with_keep_end_count("cardNumber", 4)
262
+ .with_keep_end_count("expiryDate", 2)
263
+ .with_all("cvv")
264
+ .with_keep_end_count("iban", 4)
265
+ .with_keep_end_count("accountNumber", 4)
266
+ .with_keep_end_count("reformattedAccountNumber", 4)
267
+ .with_keep_start_count("bin", 6)
268
+ .with_all("value")
269
+ .with_fixed_length("keyId", 8)
270
+ .with_fixed_length("secretKey", 8)
271
+ .with_fixed_length("publicKey", 8)
272
+ .with_fixed_length("userAuthenticationToken", 8)
273
+ .with_fixed_length("encryptedPayload", 8)
274
+ .with_fixed_length("decryptedPayload", 8)
275
+ .with_fixed_length("encryptedCustomerInput", 8)
276
+ .build
277
+
278
+ @@HEADER_OBFUSCATOR = HeaderObfuscator.builder
279
+ .with_fixed_length("Authorization", 8)
280
+ .with_fixed_length("WWW-Authenticate", 8)
281
+ .with_fixed_length("Proxy-Authenticate", 8)
282
+ .with_fixed_length("Proxy-Authorization", 8)
283
+ .with_fixed_length("X-GCS-Authentication-Token", 8)
284
+ .with_fixed_length("X-GCS-CallerPassword", 8)
285
+ .build
286
+
287
+ private_class_method :new
288
+
289
+ def self.obfuscate_body(body)
290
+ @@PROPERTY_OBFUSCATOR.obfuscate(body)
291
+ end
292
+
293
+ def self.obfuscate_header(name, value)
294
+ @@HEADER_OBFUSCATOR.obfuscate_value(name, value)
295
+ end
296
+ end # end of LoggingUtil
297
+ end
298
+ end