spree_emerchantpay_genesis 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +52 -0
- data/LICENSE +21 -0
- data/README.md +269 -0
- data/Rakefile +50 -0
- data/app/assets/images/spree/emerchantpay_logo.png +0 -0
- data/app/assets/javascripts/spree/emerchantpay_threeds.js +126 -0
- data/app/assets/javascripts/spree/frontend/card.min.js +3 -0
- data/app/assets/stylesheets/spree/emerchantpay_threeds.css +40 -0
- data/app/assets/stylesheets/spree/frontend/card.css +35 -0
- data/app/controllers/spree/api/v2/storefront/checkout_controller_decorator.rb +66 -0
- data/app/controllers/spree/api/v2/storefront/emerchantpay_notification_controller.rb +47 -0
- data/app/controllers/spree/api/v2/storefront/emerchantpay_threeds_controller.rb +61 -0
- data/app/controllers/spree/emerchantpay_threeds_controller.rb +31 -0
- data/app/helpers/spree/admin/payment_methods_helper.rb +110 -0
- data/app/helpers/spree_emerchantpay_genesis/mappers/genesis.rb +332 -0
- data/app/helpers/spree_emerchantpay_genesis/mappers/order.rb +70 -0
- data/app/helpers/spree_emerchantpay_genesis/mappers/transaction.rb +45 -0
- data/app/helpers/spree_emerchantpay_genesis/threeds_helper.rb +116 -0
- data/app/helpers/spree_emerchantpay_genesis/transaction_helper.rb +200 -0
- data/app/models/spree/gateway/emerchantpay_direct.rb +66 -0
- data/app/models/spree/payment_decorator.rb +13 -0
- data/app/models/spree/payment_processing_decorator.rb +28 -0
- data/app/models/spree_emerchantpay_genesis/base/data.rb +33 -0
- data/app/models/spree_emerchantpay_genesis/base/gateway.rb +65 -0
- data/app/models/spree_emerchantpay_genesis/data/address.rb +23 -0
- data/app/models/spree_emerchantpay_genesis/data/provider.rb +23 -0
- data/app/models/spree_emerchantpay_genesis/data/user.rb +32 -0
- data/app/models/spree_emerchantpay_genesis/db/application_record.rb +10 -0
- data/app/models/spree_emerchantpay_genesis/db/emerchantpay_payment.rb +35 -0
- data/app/models/spree_emerchantpay_genesis/genesis_provider.rb +203 -0
- data/app/repositories/spree_emerchantpay_genesis/emerchantpay_payments_repository.rb +120 -0
- data/app/repositories/spree_emerchantpay_genesis/spree_order_repository.rb +51 -0
- data/app/repositories/spree_emerchantpay_genesis/spree_payments_repository.rb +58 -0
- data/app/services/spree/payments/create_decorator.rb +63 -0
- data/app/services/spree_emerchantpay_genesis/base/payment_service.rb +83 -0
- data/app/services/spree_emerchantpay_genesis/notifications/service_handler.rb +33 -0
- data/app/services/spree_emerchantpay_genesis/sources/create_credit_card.rb +47 -0
- data/app/services/spree_emerchantpay_genesis/threeds/callback.rb +62 -0
- data/app/services/spree_emerchantpay_genesis/threeds/method_continue.rb +57 -0
- data/app/views/layouts/spree/method_continue.html.erb +17 -0
- data/app/views/spree/admin/payments/source_views/_emerchantpay_direct.html.erb +80 -0
- data/app/views/spree/checkout/payment/_emerchantpay_direct.html.erb +51 -0
- data/app/views/spree/emerchantpay_threeds/method_continue.html.erb +26 -0
- data/config/locales/en.yml +45 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20230927072418_add_emerchantpay_payments.rb +34 -0
- data/db/migrate/20231128153140_add_callback_status_to_emerchantpay_payments.rb +8 -0
- data/lib/generators/spree_emerchantpay_genesis/install/install_generator.rb +37 -0
- data/lib/spree_emerchantpay_genesis/engine.rb +38 -0
- data/lib/spree_emerchantpay_genesis/factories.rb +11 -0
- data/lib/spree_emerchantpay_genesis/version.rb +7 -0
- data/lib/spree_emerchantpay_genesis.rb +8 -0
- metadata +421 -0
@@ -0,0 +1,200 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
# Helper methods used in the transaction processing
|
3
|
+
class TransactionHelper # rubocop:disable Metrics/ClassLength
|
4
|
+
|
5
|
+
TRANSACTION_ID_PREFIX = 'sp-'.freeze
|
6
|
+
CAPTURE_ACTION = 'capture'.freeze
|
7
|
+
REFUND_ACTION = 'refund'.freeze
|
8
|
+
VOID_ACTION = 'void'.freeze
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
include Spree::Core::Engine.routes.url_helpers
|
13
|
+
|
14
|
+
# Generate Transaction Id
|
15
|
+
def generate_transaction_id
|
16
|
+
"#{TRANSACTION_ID_PREFIX}#{SecureRandom.uuid[TRANSACTION_ID_PREFIX.length..]}"[0..32].downcase
|
17
|
+
end
|
18
|
+
|
19
|
+
# Checks if the given request is asynchronous or not
|
20
|
+
def asyn?(genesis_request)
|
21
|
+
genesis_request.instance_of?(GenesisRuby::Api::Requests::Financial::Cards::Authorize3d) ||
|
22
|
+
genesis_request.instance_of?(GenesisRuby::Api::Requests::Financial::Cards::Sale3d)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check given response for success result
|
26
|
+
def success_result?(response)
|
27
|
+
response.approved? || async_result?(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Check given response for asynchronous execution
|
31
|
+
def async_result?(response)
|
32
|
+
response.pending? || response.pending_async? || response.in_progress? || response.pending_hold?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Check given response for Method Continue parameters
|
36
|
+
def threeds_secure?(response)
|
37
|
+
TransactionHelper.async_result?(response) && response.response_object&.key?(:threeds_method_url)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check given response for failure
|
41
|
+
def failure_result?(response)
|
42
|
+
response.error? || response.declined?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Generate Spree Response from Gateway action
|
46
|
+
def generate_spree_response(gateway_response)
|
47
|
+
return build_spree_response gateway_response if gateway_response.instance_of? GenesisRuby::Api::Response
|
48
|
+
return build_failure_error gateway_response if gateway_response.is_a? StandardError
|
49
|
+
|
50
|
+
gateway_response
|
51
|
+
end
|
52
|
+
|
53
|
+
# Build message from the given response
|
54
|
+
def build_message(response)
|
55
|
+
result = response.response_object
|
56
|
+
message = ''
|
57
|
+
|
58
|
+
message = result[:message] unless result[:message].nil?
|
59
|
+
message = "#{message} (#{result[:technical_message]})" unless result[:technical_message].nil?
|
60
|
+
|
61
|
+
message
|
62
|
+
end
|
63
|
+
|
64
|
+
# Fetch the given string with Genesis Ruby transaction class
|
65
|
+
def fetch_genesis_transaction_class(transaction_type)
|
66
|
+
request_class = Mappers::Transaction.for transaction_type
|
67
|
+
|
68
|
+
raise "Invalid transaction type given for #{self.class}" if request_class.nil?
|
69
|
+
|
70
|
+
request_class
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check if the given Genesis Response can be stored
|
74
|
+
def can_save_genesis_response?(response)
|
75
|
+
response_object = response.response_object
|
76
|
+
|
77
|
+
!(
|
78
|
+
response_object[:transaction_id].nil? ||
|
79
|
+
response_object[:transaction_type].nil? ||
|
80
|
+
response_object[:mode].nil?
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Fetch genesis_request_type from plugin options
|
85
|
+
def init_genesis_req(configuration, transaction_type)
|
86
|
+
request_class = TransactionHelper.fetch_genesis_transaction_class(transaction_type)
|
87
|
+
|
88
|
+
request_class&.new configuration
|
89
|
+
end
|
90
|
+
|
91
|
+
# Initialize Genesis client based on the action
|
92
|
+
def init_reference_req(action, configuration, transaction_type)
|
93
|
+
genesis_request = __send__("initialize_#{action}_client", configuration, transaction_type)
|
94
|
+
|
95
|
+
unless genesis_request
|
96
|
+
raise(GenesisRuby::Error, "Invalid #{action.capitalize} action for #{transaction_type.capitalize}")
|
97
|
+
end
|
98
|
+
|
99
|
+
genesis_request
|
100
|
+
end
|
101
|
+
|
102
|
+
# Init Notification object
|
103
|
+
def init_notification(configuration, params)
|
104
|
+
GenesisRuby::Api::Notification.new configuration, params
|
105
|
+
end
|
106
|
+
|
107
|
+
# Initialize Method Continue Transaction Request
|
108
|
+
def init_method_continue_req(configuration)
|
109
|
+
GenesisRuby::Api::Requests::Financial::Cards::Threeds::V2::MethodContinue.new configuration
|
110
|
+
end
|
111
|
+
|
112
|
+
# Fetch Redirect Url from Genesis Response
|
113
|
+
def fetch_redirect_url(options, response)
|
114
|
+
url = ''
|
115
|
+
url = options[:return_success_url] if TransactionHelper.success_result? response
|
116
|
+
url = options[:return_failure_url] if TransactionHelper.failure_result? response
|
117
|
+
url = response.response_object[:redirect_url] if response.response_object&.key? :redirect_url
|
118
|
+
url = build_threeds_secure_endpoint options, response if TransactionHelper.threeds_secure? response
|
119
|
+
|
120
|
+
{ redirect_url: url }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Generate Checksum from the response object
|
124
|
+
def generate_checksum(response_object)
|
125
|
+
Digest::MD5.hexdigest(
|
126
|
+
"#{response_object[:unique_id]}#{response_object[:amount]}#{response_object[:currency]}"
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# Build Success or Failure Spree Response
|
133
|
+
def build_spree_response(response)
|
134
|
+
return build_success_response response if success_result? response
|
135
|
+
|
136
|
+
build_failure_response response
|
137
|
+
end
|
138
|
+
|
139
|
+
# Build Success Spree Response from GenesisRuby::Api::Response
|
140
|
+
def build_success_response(response)
|
141
|
+
ActiveMerchant::Billing::Response.new true, build_message(response), test: test_mode?(response)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Build Failure Spree Response from GenesisRuby::Api:Response
|
145
|
+
def build_failure_response(response)
|
146
|
+
ActiveMerchant::Billing::Response.new false, build_message(response), test: test_mode?(response)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Build Failure Spree Response from GenesisRuby::Error
|
150
|
+
def build_failure_error(error)
|
151
|
+
ActiveMerchant::Billing::Response.new false, error.message
|
152
|
+
end
|
153
|
+
|
154
|
+
# Check the given Genesis Response mode (test/production)
|
155
|
+
def test_mode?(response)
|
156
|
+
response&.response_object&.[](:mode) == 'test'
|
157
|
+
end
|
158
|
+
|
159
|
+
# Initialize Genesis Client with Capture request
|
160
|
+
def initialize_capture_client(configuration, payment_type)
|
161
|
+
return nil unless GenesisRuby::Utils::Transactions::References::CapturableTypes.allowed_reference? payment_type
|
162
|
+
|
163
|
+
init_genesis_req(
|
164
|
+
configuration,
|
165
|
+
GenesisRuby::Utils::Transactions::References::CapturableTypes.fetch_reference(payment_type)
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Initialize Genesis Client with Refund request
|
170
|
+
def initialize_refund_client(configuration, payment_type)
|
171
|
+
return nil unless GenesisRuby::Utils::Transactions::References::RefundableTypes.allowed_reference? payment_type
|
172
|
+
|
173
|
+
init_genesis_req(
|
174
|
+
configuration,
|
175
|
+
GenesisRuby::Utils::Transactions::References::RefundableTypes.fetch_reference(payment_type)
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Initialize Genesis with Void request
|
180
|
+
def initialize_void_client(configuration, payment_type)
|
181
|
+
return nil unless GenesisRuby::Utils::Transactions::References::VoidableTypes.allowed_reference? payment_type
|
182
|
+
|
183
|
+
init_genesis_req(
|
184
|
+
configuration,
|
185
|
+
GenesisRuby::Utils::Transactions::References::VoidableTypes.fetch_reference(payment_type)
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Build 3DSv2 Method Continue endpoint
|
190
|
+
def build_threeds_secure_endpoint(options, response)
|
191
|
+
response_object = response.response_object
|
192
|
+
checksum = generate_checksum response_object
|
193
|
+
|
194
|
+
"#{options[:hostname]}#{emerchantpay_threeds_form_path(response_object[:unique_id], checksum)}"
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Spree
|
2
|
+
# Emerchantpay Direct Payment Method
|
3
|
+
class Gateway::EmerchantpayDirect < SpreeEmerchantpayGenesis::Base::Gateway # rubocop:disable Style/ClassAndModuleChildren
|
4
|
+
|
5
|
+
preference :token, :string
|
6
|
+
|
7
|
+
delegate :load_data, :load_source, :load_payment, to: :provider
|
8
|
+
|
9
|
+
def method_type
|
10
|
+
'emerchantpay_direct'
|
11
|
+
end
|
12
|
+
|
13
|
+
def provider_class
|
14
|
+
SpreeEmerchantpayGenesis::GenesisProvider
|
15
|
+
end
|
16
|
+
|
17
|
+
def provider
|
18
|
+
@provider = provider_class.new options if @provider.nil?
|
19
|
+
|
20
|
+
@provider
|
21
|
+
end
|
22
|
+
|
23
|
+
def purchase(_money_in_cents, source, gateway_options)
|
24
|
+
order, payment = order_data_from_options gateway_options
|
25
|
+
user = order.user
|
26
|
+
|
27
|
+
prepare_provider(
|
28
|
+
SpreeEmerchantpayGenesis::Mappers::Order.prepare_data(order, user, gateway_options),
|
29
|
+
source,
|
30
|
+
payment
|
31
|
+
)
|
32
|
+
|
33
|
+
provider.purchase
|
34
|
+
end
|
35
|
+
|
36
|
+
def authorize(money_in_cents, source, gateway_options)
|
37
|
+
purchase money_in_cents, source, gateway_options
|
38
|
+
end
|
39
|
+
|
40
|
+
def supports?(_source)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def source_required?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def payment_source_class
|
49
|
+
CreditCard
|
50
|
+
end
|
51
|
+
|
52
|
+
def auto_capture?
|
53
|
+
!GenesisRuby::Utils::Transactions::References::CapturableTypes.all.include? options[:transaction_types]
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Prepare provider
|
59
|
+
def prepare_provider(data, source, payment)
|
60
|
+
load_data SpreeEmerchantpayGenesis::Mappers::Order.for data
|
61
|
+
load_source source
|
62
|
+
load_payment payment
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Spree
|
2
|
+
# Spree Payment Decorator
|
3
|
+
module PaymentDecorator
|
4
|
+
|
5
|
+
# Query all Genesis Gateway Payments
|
6
|
+
def emerchantpay_payments
|
7
|
+
SpreeEmerchantpayGenesis::EmerchantpayPaymentsRepository.find_all_by_order_and_payment order.number, number
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
::Spree::Payment.prepend(Spree::PaymentDecorator)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spree
|
2
|
+
# Emerchantpay Payment Processing decorator
|
3
|
+
module PaymentProcessingDecorator
|
4
|
+
|
5
|
+
def gateway_action(source, action, success_state)
|
6
|
+
protect_from_connection_error do
|
7
|
+
response = payment_method.__send__ action, money.money.cents, source, gateway_options
|
8
|
+
success_state = fetch_state success_state, response, action
|
9
|
+
result = SpreeEmerchantpayGenesis::TransactionHelper.generate_spree_response response
|
10
|
+
handle_response(result, success_state, :failure)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Provide Spree success event method that will be executed
|
17
|
+
def fetch_state(current_state, response, action)
|
18
|
+
return current_state unless %w(purchase authorize).include? action.to_s
|
19
|
+
return current_state unless response.instance_of? GenesisRuby::Api::Response
|
20
|
+
return 'started_processing' if SpreeEmerchantpayGenesis::TransactionHelper.async_result?(response)
|
21
|
+
|
22
|
+
current_state
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
::Spree::Payment.prepend(Spree::PaymentProcessingDecorator)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Base
|
3
|
+
# Simple key value hash object
|
4
|
+
# Usage: ConfigurableOptions.<name>=, ConfigurableOptions.<name>
|
5
|
+
class Data < Hash
|
6
|
+
|
7
|
+
def []=(key, value)
|
8
|
+
super(key.to_sym, value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
super(key.to_sym)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Dynamic accessors for the hash[keys]
|
16
|
+
def method_missing(name, *args)
|
17
|
+
name_string = name.to_s
|
18
|
+
if name_string.chomp!('=')
|
19
|
+
self[name_string] = args.first
|
20
|
+
else
|
21
|
+
self[name_string]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Define ConfigurableOptions.method("<method>") call
|
26
|
+
# If we dont have defined hash key we will raise exception
|
27
|
+
def respond_to_missing?(name, include_private = false)
|
28
|
+
method_missing(name) || super
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Base
|
3
|
+
# Base Gateway object
|
4
|
+
class Gateway < Spree::Gateway
|
5
|
+
|
6
|
+
preference :username, :string
|
7
|
+
preference :password, :string
|
8
|
+
preference :transaction_types, :select, default: -> { { values: [:authorize, :authorize3d, :sale, :sale3d] } }
|
9
|
+
preference :return_success_url, :string, default: 'http://localhost:4000/orders/|:ORDER:|'
|
10
|
+
preference :return_failure_url, :string, default: 'http://localhost:4000/checkout/payment?order_number=|:ORDER:|'
|
11
|
+
preference :threeds_allowed, :boolean_select, default: true
|
12
|
+
preference :challenge_indicator, :select, default: lambda {
|
13
|
+
{ values: [:no_preference, :no_challenge_requested, :preference, :mandate] }
|
14
|
+
}
|
15
|
+
preference :hostname, :string, default: 'http://127.0.0.1:4000'
|
16
|
+
preference :test_mode, :boolean_select, default: true
|
17
|
+
|
18
|
+
# Capture authorized payment
|
19
|
+
def capture(amount, transaction_id, gateway_options)
|
20
|
+
order, payment = order_data_from_options gateway_options
|
21
|
+
|
22
|
+
prepare_provider order.attributes.symbolize_keys.merge(gateway_options), payment.source, payment
|
23
|
+
|
24
|
+
transaction = SpreeEmerchantpayGenesis::EmerchantpayPaymentsRepository.find_by_transaction_id transaction_id
|
25
|
+
|
26
|
+
provider.capture GenesisRuby::Utils::MoneyFormat.exponent_to_amount(amount, order.currency), transaction
|
27
|
+
end
|
28
|
+
|
29
|
+
# Undo a payment
|
30
|
+
def void(transaction_id, gateway_options)
|
31
|
+
order, payment = order_data_from_options gateway_options
|
32
|
+
|
33
|
+
prepare_provider order.attributes.symbolize_keys.merge(gateway_options), payment.source, payment
|
34
|
+
|
35
|
+
transaction = SpreeEmerchantpayGenesis::EmerchantpayPaymentsRepository.find_final_transaction transaction_id
|
36
|
+
|
37
|
+
provider.void transaction
|
38
|
+
end
|
39
|
+
|
40
|
+
# Refund a payment
|
41
|
+
def credit(credit_cents, transaction_id, refund_object)
|
42
|
+
payment = refund_object[:originator].payment
|
43
|
+
order = refund_object[:originator].payment.order
|
44
|
+
|
45
|
+
prepare_provider order.attributes.symbolize_keys, payment.source, payment
|
46
|
+
|
47
|
+
transaction = SpreeEmerchantpayGenesis::EmerchantpayPaymentsRepository.find_final_transaction transaction_id
|
48
|
+
|
49
|
+
provider.refund GenesisRuby::Utils::MoneyFormat.exponent_to_amount(credit_cents, order.currency), transaction
|
50
|
+
end
|
51
|
+
|
52
|
+
def payment_profiles_supported?
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
def order_data_from_options(options)
|
57
|
+
order_number, payment_number = options[:order_id].split('-')
|
58
|
+
order = Spree::Order.find_by(number: order_number)
|
59
|
+
payment = order.payments.find_by(number: payment_number)
|
60
|
+
[order, payment]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Data
|
3
|
+
# Billing and Shipping Address data
|
4
|
+
class Address < Base::Data
|
5
|
+
|
6
|
+
# Override the default zip method behaviour
|
7
|
+
def zip
|
8
|
+
self[:zip]
|
9
|
+
end
|
10
|
+
|
11
|
+
# Split name into first and last names
|
12
|
+
def name=(value)
|
13
|
+
names = value.nil? ? [] : value.split
|
14
|
+
|
15
|
+
self[:first_name] = names.first
|
16
|
+
self[:last_name] = names.last
|
17
|
+
|
18
|
+
self[:name] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Data
|
3
|
+
# Provider data
|
4
|
+
class Provider < Base::Data
|
5
|
+
|
6
|
+
# Predefine Amount accessor (BigDecimal.to_s)
|
7
|
+
def amount
|
8
|
+
return total.to_s unless total.nil?
|
9
|
+
|
10
|
+
total
|
11
|
+
end
|
12
|
+
|
13
|
+
# Override default ip accessor
|
14
|
+
# Requests via Spree API causing ip = nil
|
15
|
+
def ip
|
16
|
+
return '127.0.0.1' if self[:ip].nil?
|
17
|
+
|
18
|
+
self[:ip]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Data
|
3
|
+
# User data
|
4
|
+
class User < Base::Data
|
5
|
+
|
6
|
+
# Provide formatted Create At
|
7
|
+
def created_at_formatted
|
8
|
+
self[:created_at].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_ISO_8601)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Provide formatted Updated At
|
12
|
+
def updated_at_formatted
|
13
|
+
self[:updated_at].strftime(GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_ISO_8601)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Billing Address object
|
17
|
+
def billing_address
|
18
|
+
return nil if self[:bill_address_id].nil?
|
19
|
+
|
20
|
+
Spree::Address.find_by(id: self[:bill_address_id])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Shipping Address object
|
24
|
+
def shipping_address
|
25
|
+
return nil if self[:ship_address_id].nil?
|
26
|
+
|
27
|
+
Spree::Address.find_by(id: self[:ship_address_id])
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SpreeEmerchantpayGenesis
|
2
|
+
module Db
|
3
|
+
# EmerchantpayPayments DB model
|
4
|
+
class EmerchantpayPayment < ApplicationRecord
|
5
|
+
|
6
|
+
DATE_TIME_FORMAT = '%Y-%m-%d %H:%M'.freeze
|
7
|
+
|
8
|
+
store :request, coder: JSON
|
9
|
+
store :response, coder: JSON
|
10
|
+
|
11
|
+
# Get amount formatted in major currency
|
12
|
+
def major_amount
|
13
|
+
GenesisRuby::Utils::MoneyFormat.exponent_to_amount amount, currency
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get created_at formatted
|
17
|
+
def formatted_created_at
|
18
|
+
created_at.strftime DATE_TIME_FORMAT
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get updated_at formatted
|
22
|
+
def formatted_updated_at
|
23
|
+
updated_at.strftime DATE_TIME_FORMAT
|
24
|
+
end
|
25
|
+
|
26
|
+
# Get formatted Response Timestamp
|
27
|
+
def zulu_response_timestamp
|
28
|
+
DateTime.parse(response[:timestamp]).strftime(
|
29
|
+
GenesisRuby::Api::Constants::DateTimeFormats::YYYY_MM_DD_H_I_S_ZULU
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|