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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +158 -0
- data/LICENSE +21 -0
- data/README.md +343 -0
- data/Rakefile +12 -0
- data/VERSION +1 -0
- data/genesis_ruby.gemspec +43 -0
- data/lib/genesis_ruby/api/constants/currencies/iso4217.rb +1106 -0
- data/lib/genesis_ruby/api/constants/date_time_formats.rb +45 -0
- data/lib/genesis_ruby/api/constants/endpoints.rb +18 -0
- data/lib/genesis_ruby/api/constants/environments.rb +17 -0
- data/lib/genesis_ruby/api/constants/states/state.rb +43 -0
- data/lib/genesis_ruby/api/constants/states.rb +86 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/business/payment_types.rb +24 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/recurring/categories.rb +24 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/recurring/types.rb +28 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/sca_exemptions.rb +34 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/browser/color_depths.rb +46 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/password_change_indicators.rb +37 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/registration_indicators.rb +37 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/shipping_address_usage_indicators.rb +34 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/suspicious_activity_indicators.rb +28 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/card_holder_account/update_indicators.rb +34 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/challenge_indicators.rb +34 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/challenge_window_sizes.rb +37 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/control/device_types.rb +28 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/delivery_timeframes.rb +34 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/pre_order_purchase_indicators.rb +28 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/reorder_item_indicators.rb +28 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/merchant_risk/shipping_indicators.rb +46 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/purchase/categories.rb +43 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/sdk/interfaces.rb +31 -0
- data/lib/genesis_ruby/api/constants/transactions/parameters/threeds/version2/sdk/ui_types.rb +37 -0
- data/lib/genesis_ruby/api/constants/transactions.rb +371 -0
- data/lib/genesis_ruby/api/mixins/constants/common.rb +27 -0
- data/lib/genesis_ruby/api/mixins/requests/address_info_attributes.rb +20 -0
- data/lib/genesis_ruby/api/mixins/requests/customer_address/billing_info_attributes.rb +33 -0
- data/lib/genesis_ruby/api/mixins/requests/customer_address/customer_info_attributes.rb +26 -0
- data/lib/genesis_ruby/api/mixins/requests/customer_address/shipping_info_attributes.rb +33 -0
- data/lib/genesis_ruby/api/mixins/requests/document_attributes.rb +14 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/async_attributes.rb +34 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/base_attributes.rb +16 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/airlines_air_carriers_attributes.rb +60 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/business_attributes.rb +56 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/car_plane_and_boat_rentals_attributes.rb +53 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/cruise_lines_attributes.rb +50 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/event_management_attributes.rb +54 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/furniture_attributes.rb +53 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/hotels_and_real_estate_rentals_attributes.rb +53 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/business/travel_agencies_attributes.rb +88 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/credit_card_attributes.rb +31 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/fx_rate_attributes.rb +18 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/recurring/recurring_category_attributes.rb +31 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/recurring/recurring_type_attributes.rb +31 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/cards/tokenization_attributes.rb +39 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/crypto_attributes.rb +25 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/dynamic_descriptor_attributes.rb +114 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/gaming_attributes.rb +25 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/moto_attributes.rb +25 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/notification_attributes.rb +25 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/payment_attributes.rb +32 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/pending_payment_attributes.rb +25 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/reference_attributes.rb +16 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/risk_attributes.rb +47 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/sca_attributes.rb +37 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/browser.rb +92 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/card_holder_account.rb +183 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/common_attributes.rb +52 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/control.rb +61 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/merchant_risk.rb +114 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/method.rb +44 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/purchase.rb +42 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/recurring.rb +49 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/sdk.rb +107 -0
- data/lib/genesis_ruby/api/mixins/requests/financial/threeds/version2/wpf_attributes.rb +61 -0
- data/lib/genesis_ruby/api/mixins/requests/restricted_setter.rb +75 -0
- data/lib/genesis_ruby/api/request.rb +171 -0
- data/lib/genesis_ruby/api/requests/base/financial.rb +44 -0
- data/lib/genesis_ruby/api/requests/base/financials/credit_card.rb +27 -0
- data/lib/genesis_ruby/api/requests/financial/cards/authorize.rb +60 -0
- data/lib/genesis_ruby/api/requests/financial/cards/authorize3d.rb +76 -0
- data/lib/genesis_ruby/api/requests/financial/cards/sale.rb +59 -0
- data/lib/genesis_ruby/api/requests/financial/cards/sale3d.rb +75 -0
- data/lib/genesis_ruby/api/requests/wpf/create.rb +142 -0
- data/lib/genesis_ruby/api/response.rb +91 -0
- data/lib/genesis_ruby/builder.rb +42 -0
- data/lib/genesis_ruby/builders/base.rb +18 -0
- data/lib/genesis_ruby/builders/xml.rb +95 -0
- data/lib/genesis_ruby/configuration.rb +177 -0
- data/lib/genesis_ruby/connection.rb +20 -0
- data/lib/genesis_ruby/dependencies.rb +19 -0
- data/lib/genesis_ruby/errors/builder_error.rb +14 -0
- data/lib/genesis_ruby/errors/endpoint_not_set_error.rb +14 -0
- data/lib/genesis_ruby/errors/error.rb +18 -0
- data/lib/genesis_ruby/errors/invalid_argument_error.rb +14 -0
- data/lib/genesis_ruby/errors/network_error.rb +14 -0
- data/lib/genesis_ruby/errors/object_formatter_error.rb +14 -0
- data/lib/genesis_ruby/errors/parameter_error.rb +12 -0
- data/lib/genesis_ruby/errors/parser_error.rb +14 -0
- data/lib/genesis_ruby/errors/response_error.rb +14 -0
- data/lib/genesis_ruby/network/adapter/base_adapter.rb +31 -0
- data/lib/genesis_ruby/network/adapter/net_http_adapter.rb +92 -0
- data/lib/genesis_ruby/network/base_network.rb +83 -0
- data/lib/genesis_ruby/network/net_http.rb +28 -0
- data/lib/genesis_ruby/parser.rb +44 -0
- data/lib/genesis_ruby/parsers/base.rb +25 -0
- data/lib/genesis_ruby/parsers/xml.rb +120 -0
- data/lib/genesis_ruby/utils/common.rb +108 -0
- data/lib/genesis_ruby/utils/formatters/base.rb +40 -0
- data/lib/genesis_ruby/utils/formatters/response/definitions.rb +21 -0
- data/lib/genesis_ruby/utils/formatters/response/formats/amount.rb +34 -0
- data/lib/genesis_ruby/utils/formatters/response/formats/timestamp.rb +29 -0
- data/lib/genesis_ruby/utils/formatters/response/loader.rb +42 -0
- data/lib/genesis_ruby/utils/money/base/strategy.rb +38 -0
- data/lib/genesis_ruby/utils/money/conversions/amount_to_exponent.rb +22 -0
- data/lib/genesis_ruby/utils/money/conversions/exponent_to_amount.rb +22 -0
- data/lib/genesis_ruby/utils/money/format.rb +34 -0
- data/lib/genesis_ruby/utils/money_format.rb +39 -0
- data/lib/genesis_ruby/utils/object_formatter.rb +67 -0
- data/lib/genesis_ruby/utils/options/api_config.rb +36 -0
- data/lib/genesis_ruby/utils/options/base.rb +35 -0
- data/lib/genesis_ruby/utils/options/network_adapter_config.rb +41 -0
- data/lib/genesis_ruby/utils/transactions/financial_types.rb +50 -0
- data/lib/genesis_ruby/utils/transactions/references/capturable_types.rb +52 -0
- data/lib/genesis_ruby/utils/transactions/references/refundable_types.rb +70 -0
- data/lib/genesis_ruby/utils/transactions/references/voidable_types.rb +49 -0
- data/lib/genesis_ruby/utils/transactions/wpf_types.rb +43 -0
- data/lib/genesis_ruby/version.rb +5 -0
- data/lib/genesis_ruby.rb +57 -0
- 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 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
|