genesis_ruby 0.1.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 (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