genesis_ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +11 -0
  3. data/Gemfile +6 -0
  4. data/Gemfile.lock +158 -0
  5. data/LICENSE +21 -0
  6. data/README.md +343 -0
  7. data/Rakefile +12 -0
  8. data/VERSION +1 -0
  9. data/genesis_ruby.gemspec +43 -0
  10. data/lib/genesis_ruby/api/constants/currencies/iso4217.rb +1106 -0
  11. data/lib/genesis_ruby/api/constants/date_time_formats.rb +45 -0
  12. data/lib/genesis_ruby/api/constants/endpoints.rb +18 -0
  13. data/lib/genesis_ruby/api/constants/environments.rb +17 -0
  14. data/lib/genesis_ruby/api/constants/states/state.rb +43 -0
  15. data/lib/genesis_ruby/api/constants/states.rb +86 -0
  16. data/lib/genesis_ruby/api/constants/transactions/parameters/business/payment_types.rb +24 -0
  17. data/lib/genesis_ruby/api/constants/transactions/parameters/recurring/categories.rb +24 -0
  18. data/lib/genesis_ruby/api/constants/transactions/parameters/recurring/types.rb +28 -0
  19. data/lib/genesis_ruby/api/constants/transactions/parameters/sca_exemptions.rb +34 -0
  20. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/browser/color_depths.rb +46 -0
  21. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/password_change_indicators.rb +37 -0
  22. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/registration_indicators.rb +37 -0
  23. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/shipping_address_usage_indicators.rb +34 -0
  24. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/suspicious_activity_indicators.rb +28 -0
  25. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/update_indicators.rb +34 -0
  26. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/challenge_indicators.rb +34 -0
  27. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/challenge_window_sizes.rb +37 -0
  28. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/device_types.rb +28 -0
  29. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/delivery_timeframes.rb +34 -0
  30. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/pre_order_purchase_indicators.rb +28 -0
  31. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/reorder_item_indicators.rb +28 -0
  32. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/shipping_indicators.rb +46 -0
  33. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/purchase/categories.rb +43 -0
  34. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/sdk/interfaces.rb +31 -0
  35. data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/sdk/ui_types.rb +37 -0
  36. data/lib/genesis_ruby/api/constants/transactions.rb +371 -0
  37. data/lib/genesis_ruby/api/mixins/constants/common.rb +27 -0
  38. data/lib/genesis_ruby/api/mixins/requests/address_info_attributes.rb +20 -0
  39. data/lib/genesis_ruby/api/mixins/requests/customer_address/billing_info_attributes.rb +33 -0
  40. data/lib/genesis_ruby/api/mixins/requests/customer_address/customer_info_attributes.rb +26 -0
  41. data/lib/genesis_ruby/api/mixins/requests/customer_address/shipping_info_attributes.rb +33 -0
  42. data/lib/genesis_ruby/api/mixins/requests/document_attributes.rb +14 -0
  43. data/lib/genesis_ruby/api/mixins/requests/financial/async_attributes.rb +34 -0
  44. data/lib/genesis_ruby/api/mixins/requests/financial/base_attributes.rb +16 -0
  45. data/lib/genesis_ruby/api/mixins/requests/financial/business/airlines_air_carriers_attributes.rb +60 -0
  46. data/lib/genesis_ruby/api/mixins/requests/financial/business/business_attributes.rb +56 -0
  47. data/lib/genesis_ruby/api/mixins/requests/financial/business/car_plane_and_boat_rentals_attributes.rb +53 -0
  48. data/lib/genesis_ruby/api/mixins/requests/financial/business/cruise_lines_attributes.rb +50 -0
  49. data/lib/genesis_ruby/api/mixins/requests/financial/business/event_management_attributes.rb +54 -0
  50. data/lib/genesis_ruby/api/mixins/requests/financial/business/furniture_attributes.rb +53 -0
  51. data/lib/genesis_ruby/api/mixins/requests/financial/business/hotels_and_real_estate_rentals_attributes.rb +53 -0
  52. data/lib/genesis_ruby/api/mixins/requests/financial/business/travel_agencies_attributes.rb +88 -0
  53. data/lib/genesis_ruby/api/mixins/requests/financial/cards/credit_card_attributes.rb +31 -0
  54. data/lib/genesis_ruby/api/mixins/requests/financial/cards/fx_rate_attributes.rb +18 -0
  55. data/lib/genesis_ruby/api/mixins/requests/financial/cards/recurring/recurring_category_attributes.rb +31 -0
  56. data/lib/genesis_ruby/api/mixins/requests/financial/cards/recurring/recurring_type_attributes.rb +31 -0
  57. data/lib/genesis_ruby/api/mixins/requests/financial/cards/tokenization_attributes.rb +39 -0
  58. data/lib/genesis_ruby/api/mixins/requests/financial/crypto_attributes.rb +25 -0
  59. data/lib/genesis_ruby/api/mixins/requests/financial/dynamic_descriptor_attributes.rb +114 -0
  60. data/lib/genesis_ruby/api/mixins/requests/financial/gaming_attributes.rb +25 -0
  61. data/lib/genesis_ruby/api/mixins/requests/financial/moto_attributes.rb +25 -0
  62. data/lib/genesis_ruby/api/mixins/requests/financial/notification_attributes.rb +25 -0
  63. data/lib/genesis_ruby/api/mixins/requests/financial/payment_attributes.rb +32 -0
  64. data/lib/genesis_ruby/api/mixins/requests/financial/pending_payment_attributes.rb +25 -0
  65. data/lib/genesis_ruby/api/mixins/requests/financial/reference_attributes.rb +16 -0
  66. data/lib/genesis_ruby/api/mixins/requests/financial/risk_attributes.rb +47 -0
  67. data/lib/genesis_ruby/api/mixins/requests/financial/sca_attributes.rb +37 -0
  68. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/browser.rb +92 -0
  69. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/card_holder_account.rb +183 -0
  70. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/common_attributes.rb +52 -0
  71. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/control.rb +61 -0
  72. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/merchant_risk.rb +114 -0
  73. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/method.rb +44 -0
  74. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/purchase.rb +42 -0
  75. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/recurring.rb +49 -0
  76. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/sdk.rb +107 -0
  77. data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/wpf_attributes.rb +61 -0
  78. data/lib/genesis_ruby/api/mixins/requests/restricted_setter.rb +75 -0
  79. data/lib/genesis_ruby/api/request.rb +171 -0
  80. data/lib/genesis_ruby/api/requests/base/financial.rb +44 -0
  81. data/lib/genesis_ruby/api/requests/base/financials/credit_card.rb +27 -0
  82. data/lib/genesis_ruby/api/requests/financial/cards/authorize.rb +60 -0
  83. data/lib/genesis_ruby/api/requests/financial/cards/authorize3d.rb +76 -0
  84. data/lib/genesis_ruby/api/requests/financial/cards/sale.rb +59 -0
  85. data/lib/genesis_ruby/api/requests/financial/cards/sale3d.rb +75 -0
  86. data/lib/genesis_ruby/api/requests/wpf/create.rb +142 -0
  87. data/lib/genesis_ruby/api/response.rb +91 -0
  88. data/lib/genesis_ruby/builder.rb +42 -0
  89. data/lib/genesis_ruby/builders/base.rb +18 -0
  90. data/lib/genesis_ruby/builders/xml.rb +95 -0
  91. data/lib/genesis_ruby/configuration.rb +177 -0
  92. data/lib/genesis_ruby/connection.rb +20 -0
  93. data/lib/genesis_ruby/dependencies.rb +19 -0
  94. data/lib/genesis_ruby/errors/builder_error.rb +14 -0
  95. data/lib/genesis_ruby/errors/endpoint_not_set_error.rb +14 -0
  96. data/lib/genesis_ruby/errors/error.rb +18 -0
  97. data/lib/genesis_ruby/errors/invalid_argument_error.rb +14 -0
  98. data/lib/genesis_ruby/errors/network_error.rb +14 -0
  99. data/lib/genesis_ruby/errors/object_formatter_error.rb +14 -0
  100. data/lib/genesis_ruby/errors/parameter_error.rb +12 -0
  101. data/lib/genesis_ruby/errors/parser_error.rb +14 -0
  102. data/lib/genesis_ruby/errors/response_error.rb +14 -0
  103. data/lib/genesis_ruby/network/adapter/base_adapter.rb +31 -0
  104. data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +92 -0
  105. data/lib/genesis_ruby/network/base_network.rb +83 -0
  106. data/lib/genesis_ruby/network/net_http.rb +28 -0
  107. data/lib/genesis_ruby/parser.rb +44 -0
  108. data/lib/genesis_ruby/parsers/base.rb +25 -0
  109. data/lib/genesis_ruby/parsers/xml.rb +120 -0
  110. data/lib/genesis_ruby/utils/common.rb +108 -0
  111. data/lib/genesis_ruby/utils/formatters/base.rb +40 -0
  112. data/lib/genesis_ruby/utils/formatters/response/definitions.rb +21 -0
  113. data/lib/genesis_ruby/utils/formatters/response/formats/amount.rb +34 -0
  114. data/lib/genesis_ruby/utils/formatters/response/formats/timestamp.rb +29 -0
  115. data/lib/genesis_ruby/utils/formatters/response/loader.rb +42 -0
  116. data/lib/genesis_ruby/utils/money/base/strategy.rb +38 -0
  117. data/lib/genesis_ruby/utils/money/conversions/amount_to_exponent.rb +22 -0
  118. data/lib/genesis_ruby/utils/money/conversions/exponent_to_amount.rb +22 -0
  119. data/lib/genesis_ruby/utils/money/format.rb +34 -0
  120. data/lib/genesis_ruby/utils/money_format.rb +39 -0
  121. data/lib/genesis_ruby/utils/object_formatter.rb +67 -0
  122. data/lib/genesis_ruby/utils/options/api_config.rb +36 -0
  123. data/lib/genesis_ruby/utils/options/base.rb +35 -0
  124. data/lib/genesis_ruby/utils/options/network_adapter_config.rb +41 -0
  125. data/lib/genesis_ruby/utils/transactions/financial_types.rb +50 -0
  126. data/lib/genesis_ruby/utils/transactions/references/capturable_types.rb +52 -0
  127. data/lib/genesis_ruby/utils/transactions/references/refundable_types.rb +70 -0
  128. data/lib/genesis_ruby/utils/transactions/references/voidable_types.rb +49 -0
  129. data/lib/genesis_ruby/utils/transactions/wpf_types.rb +43 -0
  130. data/lib/genesis_ruby/version.rb +5 -0
  131. data/lib/genesis_ruby.rb +57 -0
  132. metadata +372 -0
@@ -0,0 +1,142 @@
1
+ require 'genesis_ruby/utils/transactions/wpf_types'
2
+ require 'genesis_ruby/api/constants/transactions/parameters/sca_exemptions'
3
+
4
+ module GenesisRuby
5
+ module Api
6
+ module Requests
7
+ module Wpf
8
+ # Web-Payment Form Request
9
+ class Create < Request
10
+
11
+ include Mixins::Requests::RestrictedSetter
12
+ include Mixins::Requests::Financial::PaymentAttributes
13
+ include Mixins::Requests::AddressInfoAttributes
14
+ include Mixins::Requests::Financial::AsyncAttributes
15
+ include Mixins::Requests::Financial::NotificationAttributes
16
+ include Mixins::Requests::Financial::PendingPaymentAttributes
17
+ include Mixins::Requests::Financial::Threeds::Version2::WpfAttributes
18
+ include Mixins::Requests::Financial::Cards::Recurring::RecurringTypeAttributes
19
+ include Mixins::Requests::Financial::Cards::Recurring::RecurringCategoryAttributes
20
+ include Mixins::Requests::Financial::DynamicDescriptorAttributes
21
+ include Mixins::Requests::Financial::RiskAttributes
22
+ include Mixins::Requests::Financial::Business::BusinessAttributes
23
+
24
+ attr_reader :locale, :sca_preference, :sca_exemption
25
+ attr_accessor :transaction_id, :usage, :description, :consumer_id, :return_cancel_url, :remember_card,
26
+ :lifetime, :web_payment_form_id
27
+
28
+ # The transaction types that the merchant is willing to accept payments for
29
+ def add_transaction_type(name, custom_attributes = {})
30
+ unless GenesisRuby::Utils::Transactions::WpfTypes.valid? name
31
+ raise ParameterError, 'Invalid Transaction Type given.'
32
+ end
33
+
34
+ self.transaction_types = { transaction_type: {
35
+ '@attributes': { name: name.to_s.downcase }, **custom_attributes
36
+ } }
37
+ end
38
+
39
+ # Define ISO 639-1 language code to the URL
40
+ def locale=(value)
41
+ init_api_wpf_configuration(language: value.to_s.downcase)
42
+ end
43
+
44
+ # Signifies whether to perform SCA on the transaction. At least one 3DS transaction type has to be submitted.
45
+ def sca_preference=(value)
46
+ allowed_options attribute: __method__,
47
+ allowed: [true, false],
48
+ value: value,
49
+ allow_empty: true,
50
+ error_message: 'Accepts only boolean values'
51
+ end
52
+
53
+ # Exemption for the Strong Customer Authentication. The allowed options are low_value, low_risk
54
+ def sca_exemption=(value)
55
+ sca_exemptions = GenesisRuby::Api::Constants::Transactions::Parameters::ScaExemptions
56
+
57
+ allowed_options attribute: __method__,
58
+ allowed: [sca_exemptions::LOW_VALUE, sca_exemptions::LOW_RISK],
59
+ value: value.to_s.empty? ? nil : value.to_s.downcase,
60
+ allow_empty: true
61
+ end
62
+
63
+ # Specifies the recurring type of transaction
64
+ def recurring_type=(value)
65
+ allowed_values = [
66
+ GenesisRuby::Api::Constants::Transactions::Parameters::Recurring::Types::INITIAL,
67
+ GenesisRuby::Api::Constants::Transactions::Parameters::Recurring::Types::MANAGED
68
+ ]
69
+
70
+ allowed_options attribute: __method__, allowed: allowed_values, value: value, allow_empty: true
71
+ end
72
+
73
+ protected
74
+
75
+ # Load base configuration
76
+ def init_configuration
77
+ init_xml_configuration
78
+ init_api_wpf_configuration
79
+ end
80
+
81
+ # Perform validation over the defined parameters upon request execution
82
+ def check_requirements
83
+ unless GenesisRuby::Api::Constants::Currencies::Iso4217.valid?(currency)
84
+ raise ParameterError, "Invalid Currency given with value #{currency}"
85
+ end
86
+
87
+ super
88
+ end
89
+
90
+ # Define Web-Payment Form transaction request structure
91
+ def populate_structure # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
92
+ self.tree_structure = {
93
+ wpf_payment: {
94
+ transaction_id: transaction_id,
95
+ amount: transform_amount(amount, currency),
96
+ currency: currency,
97
+ usage: usage,
98
+ description: description,
99
+ consumer_id: consumer_id,
100
+ customer_email: customer_email,
101
+ customer_phone: customer_phone,
102
+ notification_url: notification_url,
103
+ return_success_url: return_success_url,
104
+ return_failure_url: return_failure_url,
105
+ return_cancel_url: return_cancel_url,
106
+ return_pending_url: return_pending_url,
107
+ billing_address: billing_address_parameters_structure,
108
+ shipping_address: shipping_address_parameters_structure,
109
+ transaction_types: transaction_types,
110
+ business_attributes: business_attributes_structure,
111
+ remember_card: remember_card,
112
+ lifetime: lifetime,
113
+ sca_preference: sca_preference,
114
+ sca_params: {
115
+ sca_exemption: sca_exemption
116
+ },
117
+ threeds_v2_params: threeds_v2_wpf_attributes_structure,
118
+ web_payment_form_id: web_payment_form_id,
119
+ recurring_type: recurring_type,
120
+ recurring_category: recurring_category,
121
+ dynamic_descriptor_params: dynamic_descriptor_structure,
122
+ risk_params: risk_parameters_structure
123
+ }
124
+ }
125
+ end
126
+
127
+ private
128
+
129
+ attr_reader :transaction_types
130
+
131
+ # Add every transaction type to the transaction types structure
132
+ def transaction_types=(value)
133
+ @transaction_types ||= []
134
+
135
+ @transaction_types.push(value)
136
+ end
137
+
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,91 @@
1
+ require 'genesis_ruby/errors/response_error'
2
+ require 'genesis_ruby/parser'
3
+ require 'genesis_ruby/api/constants/states'
4
+ require 'genesis_ruby/api/constants/states/state'
5
+ require 'genesis_ruby/utils/object_formatter'
6
+ require 'genesis_ruby/utils/formatters/response/loader'
7
+
8
+ module GenesisRuby
9
+ module Api
10
+ # Response - process/format an incoming Genesis response
11
+ class Response
12
+
13
+ def initialize(configuration)
14
+ @configuration = configuration
15
+ @object_formatter = GenesisRuby::Utils::ObjectFormatter.new
16
+ @response_formatter = GenesisRuby::Utils::Formatters::Response::Loader.new
17
+ end
18
+
19
+ # Default Response Object initialization
20
+ def response_object
21
+ @response_object ||= {}
22
+ end
23
+
24
+ # Default Response Raw initialization
25
+ def response_raw
26
+ @response_raw ||= ''
27
+ end
28
+
29
+ # Parse the response from the given Network
30
+ def parse_response(network)
31
+ @network_context = network
32
+ @response_raw = @network_context.response_body
33
+ @response_object = load_parser(@network_context).parse_document(@response_raw)
34
+
35
+ process_response_object
36
+ end
37
+
38
+ # Dynamic Helper Methods
39
+ def method_missing(symbol)
40
+ super unless GenesisRuby::Api::Constants::States::State.handle_respond_to_states(symbol)
41
+
42
+ handle_method_missing_states(symbol)
43
+ end
44
+
45
+ # Respond to missing implementation
46
+ def respond_to_missing?(symbol, include_private = false)
47
+ GenesisRuby::Api::Constants::States::State.handle_respond_to_states(symbol) || super
48
+ end
49
+
50
+ protected
51
+
52
+ attr_reader :network_context, :parser, :configuration, :object_formatter, :response_formatter
53
+
54
+ # Load the corresponding parser based on the Network header
55
+ def load_parser(network)
56
+ @parser = GenesisRuby::Parsers.new(GenesisRuby::Parser::JSON) if network.json?
57
+
58
+ if network.xml?
59
+ @parser = GenesisRuby::Parser.new(GenesisRuby::Parser::XML)
60
+ @parser.skip_root_node
61
+ end
62
+
63
+ @parser
64
+ end
65
+
66
+ # Add dynamic Sate handling
67
+ def handle_method_missing_states(symbol)
68
+ method = symbol.to_s.downcase
69
+
70
+ state = GenesisRuby::Api::Constants::States::State.new(response_object[:status])
71
+
72
+ return state.public_send(method) if state.respond_to?(method)
73
+
74
+ false
75
+ end
76
+
77
+ # Format the Response object
78
+ def process_response_object
79
+ GenesisRuby::Utils::Common.deep_compact_empty!(@response_object) if configuration.sanitize_response
80
+
81
+ if configuration.format_response
82
+ object_formatter.formats = @response_formatter.formats
83
+ @response_object = object_formatter.format_structure(@response_object)
84
+ end
85
+
86
+ @response_object
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,42 @@
1
+ require 'genesis_ruby/builders/xml'
2
+ require 'genesis_ruby/errors/builder_error'
3
+
4
+ module GenesisRuby
5
+ # Builder handler
6
+ class Builder
7
+
8
+ # Builder XML
9
+ XML = 'xml'.freeze
10
+
11
+ # Builder JSON
12
+ JSON = 'json'.freeze
13
+
14
+ # Builder FORM
15
+ FORM = 'form'.freeze
16
+
17
+ # Initialize the Builder Interface based on the Request requirements
18
+ def initialize(request_interface)
19
+ case request_interface
20
+ when XML
21
+ @builder_context = GenesisRuby::Builders::Xml.new
22
+ else
23
+ raise GenesisRuby::BuilderError, 'Invalid Builder interface!'
24
+ end
25
+ end
26
+
27
+ # Get built document
28
+ def document
29
+ builder_context.output
30
+ end
31
+
32
+ # Parse tree-structure into Builder document
33
+ def parse_structure(structure)
34
+ builder_context.populate_nodes(structure)
35
+ end
36
+
37
+ private
38
+
39
+ attr_accessor :builder_context
40
+
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module GenesisRuby
2
+ module Builders
3
+ # Contract for every builder abstraction
4
+ class Base
5
+
6
+ # Get the Generated Builder Output
7
+ def output
8
+ raise NotImplementedError, 'Output must be implemented'
9
+ end
10
+
11
+ # Tree-structured hash representing the request structure
12
+ def populate_nodes(structure)
13
+ raise NotImplementedError, 'Populate Nodes must be implemented'
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,95 @@
1
+ require 'genesis_ruby/builders/base'
2
+ require 'nokogiri'
3
+
4
+ module GenesisRuby
5
+ module Builders
6
+ # XML, Nokogiri Builder Implementation
7
+ class Xml < Base
8
+
9
+ # Initialize Nokogiri XML Builder
10
+ def initialize
11
+ @builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8')
12
+ super
13
+ end
14
+
15
+ # Generated XMl Document
16
+ def output
17
+ builder.to_xml
18
+ end
19
+
20
+ def populate_nodes(structure)
21
+ root_element, data = if structure.length == 1
22
+ [structure.keys.first, structure.values.first]
23
+ else
24
+ ['root', structure.values.first]
25
+ end
26
+
27
+ builder.method_missing(root_element, fetch_attributes(data)) { |xml| generate(data) } unless data.nil? # rubocop:disable Lint/UnusedBlockArgument
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :builder
33
+
34
+ # Loop the Hash and build the XML Document
35
+ def generate(data)
36
+ data.each do |element_name, element_value|
37
+ if element_name.is_a?(Hash)
38
+ populate_nodes(element_name)
39
+ elsif element_value.is_a?(Array) || element_value.is_a?(Hash)
40
+ add_node element_name, element_value, fetch_attributes(element_value)
41
+ else
42
+ add_element element_name, element_value
43
+ end
44
+ end
45
+ end
46
+
47
+ # Add node
48
+ # Every node can be
49
+ # - Hash
50
+ # - Array of hashes
51
+ def add_node(node_name, node_data, attributes = {})
52
+ builder.method_missing(node_name, attributes) do
53
+ node_data.each do |element_name, element_value|
54
+ fetch_node element_name, element_value
55
+ end
56
+ end
57
+ end
58
+
59
+ # Check current node and execute build step
60
+ def fetch_node(element_name, element_value)
61
+ if element_name.is_a?(Hash)
62
+ populate_nodes element_name
63
+ elsif element_value.is_a?(Hash)
64
+ add_node element_name, element_value, fetch_attributes(element_value)
65
+ elsif element_value.is_a?(Array)
66
+ build_array element_name, element_value
67
+ else
68
+ add_element element_name, element_value
69
+ end
70
+ end
71
+
72
+ # Add a single element/tag to the XML Document
73
+ def add_element(name, value, attributes = {})
74
+ builder.method_missing(name, attributes, value)
75
+ end
76
+
77
+ # Fetch the attributes stored under the @attributes key
78
+ def fetch_attributes(element_value)
79
+ attributes = {}
80
+ attributes = element_value.fetch('@attributes'.to_sym, {}) if element_value.is_a?(Hash)
81
+ element_value.delete('@attributes'.to_sym)
82
+
83
+ attributes
84
+ end
85
+
86
+ # Build XMl Document part from Array
87
+ def build_array(element_name, element_value)
88
+ element_value.each do |tag_value|
89
+ add_element element_name, tag_value
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,177 @@
1
+ require 'genesis_ruby/api/constants/environments'
2
+ require 'genesis_ruby/api/constants/endpoints'
3
+ require 'genesis_ruby/errors/invalid_argument_error'
4
+
5
+ module GenesisRuby
6
+ # Class Configuration
7
+ #
8
+ # Store/Retrieve configuration key/values across the Genesis library
9
+ class Configuration # rubocop:disable Metrics/ClassLength
10
+
11
+ # Default Network Timeout
12
+ DEFAULT_TIMEOUT = 60
13
+
14
+ # Supported Network Connections
15
+ NETWORK_INTERFACE_NET_HTTP = 'net-http'.freeze
16
+
17
+ # Default Format Response
18
+ DEFAULT_FORMAT_RESPONSE = true
19
+
20
+ # Default sanitize Response
21
+ DEFAULT_SANITIZE_RESPONSE = true
22
+
23
+ # Genesis basic configuration - credentials, endpoint, environment, token
24
+ attr_writer :username, :password, :token, :interface, :format_response, :sanitize_response
25
+
26
+ # Configuration constructor
27
+ def initialize
28
+ @environment = GenesisRuby::Api::Constants::Environments::STAGING
29
+ @sub_domains = available_sub_domains
30
+ end
31
+
32
+ # Genesis Username
33
+ def username
34
+ @username ||= ''
35
+ end
36
+
37
+ # Genesis Password
38
+ def password
39
+ @password ||= ''
40
+ end
41
+
42
+ # Genesis Token required from some of the requests
43
+ def token
44
+ @token ||= ''
45
+ end
46
+
47
+ # Genesis Environment
48
+ def environment
49
+ @environment ||= ''
50
+ end
51
+
52
+ # Genesis endpoint
53
+ def endpoint
54
+ @endpoint ||= ''
55
+ end
56
+
57
+ # Genesis Request Timeout
58
+ def timeout
59
+ @timeout ||= DEFAULT_TIMEOUT
60
+ end
61
+
62
+ # Genesis Request Timeout
63
+ def timeout=(value)
64
+ timeout = value.to_i
65
+
66
+ @timeout = timeout <= 0 ? DEFAULT_TIMEOUT : timeout
67
+ end
68
+
69
+ # Network Interface used for executing requests
70
+ def interface
71
+ @interface ||= NETWORK_INTERFACE_NET_HTTP
72
+ end
73
+
74
+ # Get a sub-domain host based on the environment
75
+ def sub_domain(sub)
76
+ return @sub_domains[sub.to_sym][@environment] if @sub_domains.key?(sub.to_sym)
77
+
78
+ nil
79
+ end
80
+
81
+ # Environment setter
82
+ def environment=(environment)
83
+ environment_argument = environment.downcase
84
+ parsed_env = nil
85
+
86
+ environment_aliases.each do |available_env, env_alias|
87
+ parsed_env = available_env if env_alias.include? environment_argument
88
+ end
89
+
90
+ raise InvalidArgumentError, 'Invalid Environment' if parsed_env.nil?
91
+
92
+ @environment = parsed_env
93
+ end
94
+
95
+ # Endpoint setter
96
+ def endpoint=(endpoint)
97
+ endpoint_argument = endpoint.downcase
98
+ parsed_endpoint = nil
99
+
100
+ endpoint_aliases.each do |available_end, endpoint_alias|
101
+ parsed_endpoint = available_end if endpoint_alias.include? endpoint_argument
102
+ end
103
+
104
+ raise InvalidArgumentError, 'Invalid Endpoint' if parsed_endpoint.nil?
105
+
106
+ @endpoint = parsed_endpoint
107
+ end
108
+
109
+ # Indicates if the parsed Response from Genesis should be formatted
110
+ def format_response
111
+ return @format_response = DEFAULT_FORMAT_RESPONSE if @format_response.nil?
112
+
113
+ @format_response
114
+ end
115
+
116
+ # Indicates if the parsed Response from Genesis should be sanitized
117
+ def sanitize_response
118
+ return @sanitize_response = DEFAULT_SANITIZE_RESPONSE if @sanitize_response.nil?
119
+
120
+ @sanitize_response
121
+ end
122
+
123
+ private
124
+
125
+ # Various definitions for environment
126
+ # rubocop:disable Metrics/MethodLength
127
+ def environment_aliases
128
+ {
129
+ GenesisRuby::Api::Constants::Environments::STAGING => [
130
+ 'test',
131
+ 'testing',
132
+ 'staging',
133
+ GenesisRuby::Api::Constants::Environments::STAGING
134
+ ],
135
+ GenesisRuby::Api::Constants::Environments::PRODUCTION => [
136
+ 'live',
137
+ 'prod',
138
+ 'production',
139
+ GenesisRuby::Api::Constants::Environments::PRODUCTION
140
+ ]
141
+ }
142
+ end
143
+
144
+ # Various definitions for Genesis endpoint
145
+ def endpoint_aliases
146
+ {
147
+ GenesisRuby::Api::Constants::Endpoints::EMERCHANTPAY => [
148
+ 'emp',
149
+ 'emerchantpay',
150
+ GenesisRuby::Api::Constants::Endpoints::EMERCHANTPAY
151
+ ],
152
+ GenesisRuby::Api::Constants::Endpoints::ECOMPROCESSING => [
153
+ 'ecp',
154
+ 'ecomprocessing',
155
+ 'e-comprocessing',
156
+ GenesisRuby::Api::Constants::Endpoints::ECOMPROCESSING
157
+ ]
158
+ }
159
+ end
160
+ # rubocop:enable Metrics/MethodLength
161
+
162
+ # Available Genesis subdomains
163
+ def available_sub_domains
164
+ {
165
+ gateway: {
166
+ GenesisRuby::Api::Constants::Environments::PRODUCTION => 'gate.',
167
+ GenesisRuby::Api::Constants::Environments::STAGING => 'staging.gate.'
168
+ },
169
+ wpf: {
170
+ GenesisRuby::Api::Constants::Environments::PRODUCTION => 'wpf.',
171
+ GenesisRuby::Api::Constants::Environments::STAGING => 'staging.wpf.'
172
+ }
173
+ }
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,20 @@
1
+ require 'genesis_ruby/network/net_http'
2
+ require 'genesis_ruby/errors/network_error'
3
+ require 'genesis_ruby/configuration'
4
+
5
+ module GenesisRuby
6
+ # Prepare the Network connection used for sending the current request
7
+ class Connection
8
+
9
+ # Initialize Network Factory based on the Configuration
10
+ def self.for(configuration)
11
+ case configuration.interface
12
+ when GenesisRuby::Configuration::NETWORK_INTERFACE_NET_HTTP
13
+ GenesisRuby::Network::NetHttp.new(configuration)
14
+ else
15
+ raise GenesisRuby::NetworkError, 'Invalid network interface given.'
16
+ end
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # =================================
2
+ # Transaction Request Requirements
3
+ # =================================
4
+ require 'genesis_ruby/api/request'
5
+ require 'genesis_ruby/api/mixins/constants/common'
6
+ require 'genesis_ruby/api/mixins/requests/restricted_setter'
7
+
8
+ # =================================
9
+ # Transaction Requests Definitions
10
+ # =================================
11
+
12
+ # Load API Attributes
13
+ Dir["#{File.dirname(__FILE__)}/api/mixins/**/*_attributes.rb"].sort.each { |file| require file }
14
+
15
+ # Load Financial and Non Financial API Requests
16
+ Dir["#{File.dirname(__FILE__)}/api/requests/*financial/**/*.rb"].sort.each { |file| require file }
17
+
18
+ # Load WPF API Requests
19
+ Dir["#{File.dirname(__FILE__)}/api/requests/wpf/**/*.rb"].sort.each { |file| require file }
@@ -0,0 +1,14 @@
1
+ require 'genesis_ruby/errors/error'
2
+
3
+ module GenesisRuby
4
+ # Invalid Argument Custom Error
5
+ class BuilderError < Error
6
+
7
+ def custom_message
8
+ return 'Unknown error during building the request!' unless @message
9
+
10
+ @message
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'genesis_ruby/errors/error'
2
+
3
+ module GenesisRuby
4
+ # Invalid Argument Custom Error
5
+ class EndpointNotSetError < Error
6
+
7
+ def custom_message
8
+ return 'No working endpoint has been set, please choose between emp/ecp endpoint!' unless @message
9
+
10
+ @message
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module GenesisRuby
2
+ # Base Genesis Ruby Error
3
+ class Error < StandardError
4
+
5
+ # Predefined error message
6
+ def custom_message
7
+ @message
8
+ end
9
+
10
+ # Customer errors constructor
11
+ def initialize(msg = nil)
12
+ @message = msg
13
+
14
+ super(custom_message)
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ require 'genesis_ruby/errors/error'
2
+
3
+ module GenesisRuby
4
+ # Invalid Argument Custom Error
5
+ class InvalidArgumentError < Error
6
+
7
+ def custom_message
8
+ return 'The supplied argument is invalid for this method!' unless @message
9
+
10
+ @message
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'genesis_ruby/errors/error'
2
+
3
+ module GenesisRuby
4
+ # Invalid Argument Custom Error
5
+ class NetworkError < Error
6
+
7
+ def custom_message
8
+ return 'Unknown error during network request!' unless @message
9
+
10
+ @message
11
+ end
12
+
13
+ end
14
+ end