flowcommerce_spree 0.0.3 → 0.0.4
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 +4 -4
- data/app/controllers/concerns/current_zone_loader_decorator.rb +5 -6
- data/app/controllers/flowcommerce_spree/inventory_controller.rb +23 -0
- data/app/controllers/flowcommerce_spree/orders_controller.rb +18 -0
- data/app/controllers/users/sessions_controller_decorator.rb +19 -2
- data/app/helpers/spree/core/controller_helpers/flow_io_order_helper_decorator.rb +0 -16
- data/app/models/spree/address_decorator.rb +1 -1
- data/app/models/spree/calculator/flow_io.rb +1 -1
- data/app/models/spree/flow_io_credit_card_decorator.rb +21 -0
- data/app/models/spree/{order_decorator.rb → flow_io_order_decorator.rb} +31 -65
- data/app/models/spree/gateway/flow_io.rb +61 -24
- data/app/models/spree/{credit_card_decorator.rb → payment_capture_event_decorator.rb} +1 -1
- data/app/serializers/api/v2/order_serializer_decorator.rb +20 -0
- data/app/services/flowcommerce_spree/import_experience_items.rb +1 -1
- data/app/services/flowcommerce_spree/order_sync.rb +26 -155
- data/app/services/flowcommerce_spree/order_updater.rb +76 -0
- data/app/views/spree/admin/payments/source_views/_flow_io_gateway.html.erb +21 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20201021755957_add_meta_to_spree_tables.rb +6 -4
- data/lib/flow/simple_gateway.rb +0 -36
- data/lib/flowcommerce_spree.rb +3 -1
- data/lib/flowcommerce_spree/engine.rb +1 -1
- data/lib/flowcommerce_spree/logging_http_client.rb +29 -13
- data/lib/flowcommerce_spree/session.rb +0 -18
- data/lib/flowcommerce_spree/version.rb +1 -1
- data/lib/flowcommerce_spree/webhook_service.rb +74 -104
- metadata +10 -19
- data/app/models/spree/line_item_decorator.rb +0 -15
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Api::V2::OrderSerializer.class_eval do
|
4
|
+
attribute :duty_included, if: proc { object.flow_io_attributes.present? }
|
5
|
+
attribute :vat_included, if: proc { object.flow_io_attributes.present? }
|
6
|
+
|
7
|
+
def duty_included
|
8
|
+
flow_io_order_attributes&.[]('duty') == 'included'
|
9
|
+
end
|
10
|
+
|
11
|
+
def vat_included
|
12
|
+
flow_io_order_attributes&.[]('vat') == 'included'
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def flow_io_order_attributes
|
18
|
+
@flow_io_order_attributes ||= Oj.load(object.flow_io_attributes['pricing_key'])
|
19
|
+
end
|
20
|
+
end
|
@@ -13,7 +13,7 @@ module FlowcommerceSpree
|
|
13
13
|
items = []
|
14
14
|
total = 0
|
15
15
|
|
16
|
-
while offset == 0 || items.length
|
16
|
+
while offset == 0 || items.length != 0
|
17
17
|
# show current list size
|
18
18
|
@logger.info "\nGetting items: #{@experience_key.green}, rows #{offset} - #{offset + page_size}"
|
19
19
|
|
@@ -16,41 +16,30 @@ module FlowcommerceSpree
|
|
16
16
|
# flow_order.synchronize! # sends order to flow
|
17
17
|
class OrderSync # rubocop:disable Metrics/ClassLength
|
18
18
|
FLOW_CENTER = 'default'
|
19
|
-
SESSION_EXPIRATION_THRESHOLD = 10 # Refresh session if less than 10 seconds to session expiration remains
|
20
19
|
|
21
|
-
attr_reader :
|
20
|
+
attr_reader :order, :response
|
22
21
|
|
23
22
|
delegate :url_helpers, to: 'Rails.application.routes'
|
24
23
|
|
25
|
-
|
26
|
-
def clear_cache(order)
|
27
|
-
return unless order.flow_data['order']
|
28
|
-
|
29
|
-
order.flow_data.delete('order')
|
30
|
-
order.update_column :meta, order.meta.to_json
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def initialize(order:)
|
24
|
+
def initialize(order:, flow_session_id:)
|
35
25
|
raise(ArgumentError, 'Experience not defined or not active') unless order.zone&.flow_io_active_experience?
|
36
26
|
|
37
27
|
@experience = order.flow_io_experience_key
|
28
|
+
@flow_session_id = flow_session_id
|
38
29
|
@order = order
|
39
|
-
@client = FlowcommerceSpree.client(session_id:
|
30
|
+
@client = FlowcommerceSpree.client(session_id: flow_session_id)
|
40
31
|
end
|
41
32
|
|
42
33
|
# helper method to send complete order from Spree to flow.io
|
43
34
|
def synchronize!
|
35
|
+
return unless @order.zone&.flow_io_active_experience? && @order.state == 'cart' && @order.line_items.size > 0
|
36
|
+
|
44
37
|
sync_body!
|
45
|
-
check_state!
|
46
38
|
write_response_in_cache
|
47
39
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
refresh_checkout_token if @order.flow_io_checkout_token.blank?
|
52
|
-
@order.update_column(:meta, @order.meta.to_json)
|
53
|
-
@response
|
40
|
+
@order.update_columns(total: @order.total, meta: @order.meta.to_json)
|
41
|
+
refresh_checkout_token
|
42
|
+
@checkout_token
|
54
43
|
end
|
55
44
|
|
56
45
|
def error
|
@@ -65,46 +54,6 @@ module FlowcommerceSpree
|
|
65
54
|
@response&.[]('code') && @response&.[]('messages') ? true : false
|
66
55
|
end
|
67
56
|
|
68
|
-
def delivery
|
69
|
-
deliveries.select { |el| el[:active] }.first
|
70
|
-
end
|
71
|
-
|
72
|
-
# delivery methods are defined in flow console
|
73
|
-
def deliveries
|
74
|
-
# if we have error with an order, but still using this method
|
75
|
-
return [] unless @order.flow_order
|
76
|
-
|
77
|
-
@order.flow_data ||= {}
|
78
|
-
|
79
|
-
delivery_list = @order.flow_order['deliveries'][0]['options'].map do |opts|
|
80
|
-
name = opts['tier']['name']
|
81
|
-
|
82
|
-
# add original Flow ID
|
83
|
-
# name += ' (%s)' % opts['tier']['strategy'] if opts['tier']['strategy']
|
84
|
-
|
85
|
-
selection_id = opts['id']
|
86
|
-
|
87
|
-
{ id: selection_id,
|
88
|
-
price: { label: opts['price']['label'] },
|
89
|
-
active: @order.flow_order['selections'].include?(selection_id),
|
90
|
-
name: name }
|
91
|
-
end.to_a
|
92
|
-
|
93
|
-
# make first one active unless we have active element
|
94
|
-
delivery_list.first[:active] = true unless delivery_list.select { |el| el[:active] }.first
|
95
|
-
|
96
|
-
delivery_list
|
97
|
-
end
|
98
|
-
|
99
|
-
def total_price
|
100
|
-
@order.flow_total
|
101
|
-
end
|
102
|
-
|
103
|
-
def delivered_duty
|
104
|
-
# paid is default
|
105
|
-
@order.flow_data['delivered_duty'] || ::Io::Flow::V0::Models::DeliveredDuty.paid.value
|
106
|
-
end
|
107
|
-
|
108
57
|
# builds object that can be sent to api.flow.io to sync order data
|
109
58
|
def build_flow_request
|
110
59
|
@opts = { experience: @experience, expand: ['experience'] }
|
@@ -112,94 +61,31 @@ module FlowcommerceSpree
|
|
112
61
|
|
113
62
|
try_to_add_customer
|
114
63
|
|
115
|
-
|
116
|
-
@body[:selections] = flow_data['selections'].presence
|
117
|
-
@body[:delivered_duty] = flow_data['delivered_duty'].presence
|
118
|
-
@body[:attributes] = flow_data['attributes'].presence
|
64
|
+
return unless (flow_data = @order.flow_data['order'])
|
119
65
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
124
|
-
end
|
66
|
+
@body[:selections] = flow_data['selections'].presence
|
67
|
+
@body[:delivered_duty] = flow_data['delivered_duty'].presence
|
68
|
+
@body[:attributes] = flow_data['attributes'].presence
|
125
69
|
|
126
|
-
#
|
127
|
-
@
|
70
|
+
# discount on full order is applied
|
71
|
+
@body[:discount] = { amount: @order.adjustment_total, currency: @order.currency } if @order.adjustment_total != 0
|
128
72
|
end
|
129
73
|
|
130
74
|
private
|
131
75
|
|
132
|
-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
133
|
-
def fetch_session_id
|
134
|
-
session = RequestStore.store[:session]
|
135
|
-
current_session_id = session&.[]('_f60_session')
|
136
|
-
session_expire_at = session&.[]('_f60_expires_at')&.to_datetime
|
137
|
-
session_expired = flow_io_session_expired?(session_expire_at.to_i)
|
138
|
-
order_flow_session_id = @order.flow_data['session_id']
|
139
|
-
order_session_expire_at = @order.flow_io_session_expires_at
|
140
|
-
order_session_expired = flow_io_session_expired?(order_session_expire_at.to_i)
|
141
|
-
|
142
|
-
if order_flow_session_id == current_session_id && session_expire_at == order_session_expire_at &&
|
143
|
-
@order.flow_io_checkout_token.present? && session_expired == false
|
144
|
-
return current_session_id
|
145
|
-
elsif current_session_id && session_expire_at && session_expired == false
|
146
|
-
# If request flow_session is not expired, don't refresh the flow_session (i.e., don't mark the refresh_session
|
147
|
-
# lvar as true), just store the flow_session data into the order, if it is new, and refresh the checkout_token
|
148
|
-
refresh_session = nil
|
149
|
-
elsif order_flow_session_id && order_session_expire_at && order_session_expired == false && session_expired.nil?
|
150
|
-
refresh_checkout_token if @order.flow_io_order_id && @order.flow_io_checkout_token.blank?
|
151
|
-
return order_flow_session_id
|
152
|
-
else
|
153
|
-
refresh_session = true
|
154
|
-
end
|
155
|
-
|
156
|
-
if refresh_session
|
157
|
-
flow_io_session = Session.new(
|
158
|
-
ip: '127.0.0.1',
|
159
|
-
visitor: "session-#{Digest::SHA1.hexdigest(@order.guest_token)}",
|
160
|
-
experience: @experience
|
161
|
-
)
|
162
|
-
flow_io_session.create
|
163
|
-
current_session_id = flow_io_session.id
|
164
|
-
session_expire_at = flow_io_session.expires_at.to_s
|
165
|
-
end
|
166
|
-
|
167
|
-
@order.flow_data['session_id'] = current_session_id
|
168
|
-
@order.flow_data['session_expires_at'] = session_expire_at
|
169
|
-
|
170
|
-
if session.respond_to?(:[])
|
171
|
-
session['_f60_session'] = current_session_id
|
172
|
-
session['_f60_expires_at'] = session_expire_at
|
173
|
-
end
|
174
|
-
|
175
|
-
# On the 1st OrderSync at this moment the order is not yet created at flow.io, so we couldn't yet retrieve the
|
176
|
-
# checkout_token. This is done after the order will be synced, in the `synchronize!` method.
|
177
|
-
refresh_checkout_token if @order.flow_io_order_id
|
178
|
-
|
179
|
-
current_session_id
|
180
|
-
end
|
181
|
-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
182
|
-
|
183
|
-
def flow_io_session_expired?(expiration_time)
|
184
|
-
return nil if expiration_time == 0
|
185
|
-
|
186
|
-
expiration_time - Time.zone.now.utc.to_i < SESSION_EXPIRATION_THRESHOLD
|
187
|
-
end
|
188
|
-
|
189
76
|
def refresh_checkout_token
|
190
77
|
root_url = url_helpers.root_url
|
191
78
|
order_number = @order.number
|
192
|
-
confirmation_url = "#{root_url}
|
193
|
-
checkout_token = FlowcommerceSpree.client.checkout_tokens.post_checkout_and_tokens_by_organization(
|
79
|
+
confirmation_url = "#{root_url}flow/order-completed?order=#{order_number}&t=#{@order.guest_token}"
|
80
|
+
@checkout_token = FlowcommerceSpree.client.checkout_tokens.post_checkout_and_tokens_by_organization(
|
194
81
|
FlowcommerceSpree::ORGANIZATION,
|
195
82
|
discriminator: 'checkout_token_reference_form',
|
196
83
|
order_number: order_number,
|
197
|
-
session_id: @
|
84
|
+
session_id: @flow_session_id,
|
198
85
|
urls: { continue_shopping: root_url,
|
199
86
|
confirmation: confirmation_url,
|
200
87
|
invalid_checkout: root_url }
|
201
|
-
)
|
202
|
-
@order.add_flow_checkout_token(checkout_token.id)
|
88
|
+
)&.id
|
203
89
|
|
204
90
|
@order.flow_io_attribute_add('flow_return_url', confirmation_url)
|
205
91
|
@order.flow_io_attribute_add('checkout_continue_shopping_url', root_url)
|
@@ -244,16 +130,13 @@ module FlowcommerceSpree
|
|
244
130
|
end
|
245
131
|
|
246
132
|
def sync_body!
|
247
|
-
build_flow_request
|
133
|
+
build_flow_request
|
248
134
|
|
249
135
|
@use_get = false
|
250
136
|
|
251
137
|
# use get if order is completed and closed
|
252
138
|
@use_get = true if @order.flow_data.dig('order', 'submitted_at').present? || @order.state == 'complete'
|
253
139
|
|
254
|
-
# use get if local digest hash check said there is no change
|
255
|
-
@use_get ||= true if @order.flow_data['digest'] == @digest
|
256
|
-
|
257
140
|
# do not use get if there is no local order cache
|
258
141
|
@use_get = false unless @order.flow_data['order']
|
259
142
|
|
@@ -265,19 +148,6 @@ module FlowcommerceSpree
|
|
265
148
|
end
|
266
149
|
end
|
267
150
|
|
268
|
-
def check_state!
|
269
|
-
# authorize if not authorized
|
270
|
-
# if !@order.flow_order_authorized?
|
271
|
-
|
272
|
-
# authorize payment on complete, unless authorized
|
273
|
-
if @order.state == 'complete' && !@order.flow_order_authorized?
|
274
|
-
simple_gateway = Flow::SimpleGateway.new(@order)
|
275
|
-
simple_gateway.cc_authorization
|
276
|
-
end
|
277
|
-
|
278
|
-
@order.flow_finalize! if @order.flow_order_authorized? && @order.state != 'complete'
|
279
|
-
end
|
280
|
-
|
281
151
|
def add_item(line_item)
|
282
152
|
variant = line_item.variant
|
283
153
|
price_root = variant.flow_data&.dig('exp', @experience, 'prices')&.[](0) || {}
|
@@ -294,17 +164,18 @@ module FlowcommerceSpree
|
|
294
164
|
# written in flow_data field inside spree_orders table
|
295
165
|
def write_response_in_cache
|
296
166
|
if !@response || error?
|
297
|
-
@order.flow_data.delete('digest')
|
298
167
|
@order.flow_data.delete('order')
|
299
168
|
else
|
300
|
-
response_total = @response
|
301
|
-
|
169
|
+
response_total = @response[:total]
|
170
|
+
response_total_label = response_total&.[](:label)
|
171
|
+
cache_total = @order.flow_data.dig('order', 'total', 'label')
|
302
172
|
|
303
173
|
# return if total is not changed, no products removed or added
|
304
|
-
return if @use_get &&
|
174
|
+
return if @use_get && response_total_label == cache_total
|
305
175
|
|
306
176
|
# update local order
|
307
|
-
@order.
|
177
|
+
@order.total = response_total&.[](:amount)
|
178
|
+
@order.flow_data.merge!('order' => @response)
|
308
179
|
end
|
309
180
|
end
|
310
181
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FlowcommerceSpree
|
4
|
+
class OrderUpdater
|
5
|
+
def initialize(order:)
|
6
|
+
raise(ArgumentError, 'Experience not defined or not active') unless order&.zone&.flow_io_active_experience?
|
7
|
+
|
8
|
+
@experience = order.flow_io_experience_key
|
9
|
+
@order = order
|
10
|
+
@client = FlowcommerceSpree.client
|
11
|
+
end
|
12
|
+
|
13
|
+
def upsert_data(flow_io_order = nil)
|
14
|
+
return if @order.state == 'complete'
|
15
|
+
|
16
|
+
flow_io_order ||= @client.orders.get_by_number(FlowcommerceSpree::ORGANIZATION, @order.number).to_hash
|
17
|
+
|
18
|
+
@order.flow_data['order'] = flow_io_order
|
19
|
+
return if @order.flow_data.dig('order', 'submitted_at').blank?
|
20
|
+
|
21
|
+
attrs_to_update = { meta: @order.meta.to_json, email: @order.flow_customer_email, payment_state: 'pending' }
|
22
|
+
attrs_to_update.merge!(@order.prepare_flow_addresses)
|
23
|
+
@order.update_columns(attrs_to_update)
|
24
|
+
@order.state = 'delivery'
|
25
|
+
@order.save!
|
26
|
+
@order.create_proposed_shipments
|
27
|
+
@order.shipment.update_amounts
|
28
|
+
@order.line_items.each(&:store_ets)
|
29
|
+
@order.charge_taxes
|
30
|
+
|
31
|
+
@order.state = 'payment'
|
32
|
+
@order.save!
|
33
|
+
end
|
34
|
+
|
35
|
+
def finalize_order
|
36
|
+
@order.reload
|
37
|
+
@order.finalize!
|
38
|
+
@order.update_totals
|
39
|
+
@order.save
|
40
|
+
@order.after_completed_order
|
41
|
+
end
|
42
|
+
|
43
|
+
def complete_checkout
|
44
|
+
upsert_data
|
45
|
+
map_payments_to_spree
|
46
|
+
finalize_order if @order.state == 'complete'
|
47
|
+
end
|
48
|
+
|
49
|
+
def map_payments_to_spree
|
50
|
+
@order.flow_io_payments&.each do |p|
|
51
|
+
payment =
|
52
|
+
@order.payments.find_or_initialize_by(response_code: p['reference'], payment_method_id: payment_method_id)
|
53
|
+
next unless payment.new_record?
|
54
|
+
|
55
|
+
payment.amount = p.dig('total', 'amount')
|
56
|
+
payment.pend
|
57
|
+
|
58
|
+
# For now this additional update is overwriting the generated identifier with flow.io payment identifier.
|
59
|
+
# TODO: Check and possibly refactor in Spree 3.0, where the `before_create :set_unique_identifier`
|
60
|
+
# has been removed.
|
61
|
+
payment.update_column(:identifier, p['id'])
|
62
|
+
end
|
63
|
+
|
64
|
+
return if @order.payments.sum(:amount) < @order.amount || @order.state == 'complete'
|
65
|
+
|
66
|
+
@order.state = 'confirm'
|
67
|
+
@order.save!
|
68
|
+
@order.state = 'complete'
|
69
|
+
@order.save!
|
70
|
+
end
|
71
|
+
|
72
|
+
def payment_method_id
|
73
|
+
@payment_method_id ||= Spree::PaymentMethod.find_by(active: true, type: 'Spree::Gateway::FlowIo').id
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<fieldset data-hook="credit_card">
|
2
|
+
<legend align="center"><%= Spree.t(:credit_card) %></legend>
|
3
|
+
|
4
|
+
<div class="row">
|
5
|
+
<div class="alpha six columns">
|
6
|
+
<dl>
|
7
|
+
<dt><%= Spree.t(:name_on_card) %>:</dt>
|
8
|
+
<dd><%= payment.source&.name %></dd>
|
9
|
+
|
10
|
+
<dt><%= Spree.t(:card_type) %>:</dt>
|
11
|
+
<dd><%= payment.source&.cc_type %></dd>
|
12
|
+
|
13
|
+
<dt><%= Spree.t(:card_number) %>:</dt>
|
14
|
+
<dd><%= payment.source&.display_number %></dd>
|
15
|
+
|
16
|
+
<dt><%= Spree.t(:expiration) %>:</dt>
|
17
|
+
<dd><%= payment.source&.month %>/<%= payment.source&.year %></dd>
|
18
|
+
</dl>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</fieldset>
|
data/config/routes.rb
CHANGED
@@ -5,13 +5,15 @@ class AddMetaToSpreeTables < ActiveRecord::Migration
|
|
5
5
|
add_column :spree_orders, :meta, :jsonb, default: '{}' unless column_exists?(:spree_orders, :meta)
|
6
6
|
add_column :spree_promotions, :meta, :jsonb, default: '{}' unless column_exists?(:spree_promotions, :meta)
|
7
7
|
add_column :spree_credit_cards, :meta, :jsonb, default: '{}' unless column_exists?(:spree_credit_cards, :meta)
|
8
|
+
add_column :spree_payment_capture_events, :meta, :jsonb, default: '{}' unless column_exists?(:spree_payment_capture_events, :meta)
|
8
9
|
end
|
9
10
|
|
10
11
|
def down
|
11
|
-
remove_column :
|
12
|
-
remove_column :spree_variants, :meta if column_exists?(:spree_variants, :meta)
|
13
|
-
remove_column :spree_orders, :meta if column_exists?(:spree_orders, :meta)
|
14
|
-
remove_column :spree_promotions, :meta if column_exists?(:spree_promotions, :meta)
|
12
|
+
remove_column :spree_payment_capture_events, :meta if column_exists?(:spree_payment_capture_events, :meta)
|
15
13
|
remove_column :spree_credit_cards, :meta if column_exists?(:spree_credit_cards, :meta)
|
14
|
+
remove_column :spree_promotions, :meta if column_exists?(:spree_promotions, :meta)
|
15
|
+
remove_column :spree_orders, :meta if column_exists?(:spree_orders, :meta)
|
16
|
+
remove_column :spree_variants, :meta if column_exists?(:spree_variants, :meta)
|
17
|
+
remove_column :spree_products, :meta if column_exists?(:spree_products, :meta)
|
16
18
|
end
|
17
19
|
end
|
data/lib/flow/simple_gateway.rb
CHANGED
@@ -34,42 +34,6 @@ module Flow
|
|
34
34
|
error_response(e)
|
35
35
|
end
|
36
36
|
|
37
|
-
# capture authorised funds
|
38
|
-
def cc_capture
|
39
|
-
# GET /:organization/authorizations, order_number: abc
|
40
|
-
data = @order.flow_data['authorization']
|
41
|
-
|
42
|
-
raise ArgumentError, 'No Authorization data, please authorize first' unless data
|
43
|
-
|
44
|
-
capture_form = ::Io::Flow::V0::Models::CaptureForm.new(data)
|
45
|
-
response = FlowcommerceSpree.client.captures.post(FlowcommerceSpree::ORGANIZATION, capture_form)
|
46
|
-
|
47
|
-
return ActiveMerchant::Billing::Response.new false, 'error', response: response unless response.id
|
48
|
-
|
49
|
-
@order.update_column :flow_data, @order.flow_data.merge('capture': response.to_hash)
|
50
|
-
@order.flow_finalize!
|
51
|
-
|
52
|
-
ActiveMerchant::Billing::Response.new true, 'success', response: response
|
53
|
-
rescue StandardError => e
|
54
|
-
error_response(e)
|
55
|
-
end
|
56
|
-
|
57
|
-
def cc_refund
|
58
|
-
raise ArgumentError, 'capture info is not available' unless @order.flow_data['capture']
|
59
|
-
|
60
|
-
# we allways have capture ID, so we use it
|
61
|
-
refund_data = { capture_id: @order.flow_data['capture']['id'] }
|
62
|
-
refund_form = ::Io::Flow::V0::Models::RefundForm.new(refund_data)
|
63
|
-
response = FlowcommerceSpree.client.refunds.post(FlowcommerceSpree::ORGANIZATION, refund_form)
|
64
|
-
|
65
|
-
return ActiveMerchant::Billing::Response.new false, 'error', response: response unless response.id
|
66
|
-
|
67
|
-
@order.update_column :flow_data, @order.flow_data.merge('refund': response.to_hash)
|
68
|
-
ActiveMerchant::Billing::Response.new true, 'success', response: response
|
69
|
-
rescue StandardError => e
|
70
|
-
error_response(e)
|
71
|
-
end
|
72
|
-
|
73
37
|
private
|
74
38
|
|
75
39
|
# if order is not in flow, we use local Spree settings
|