spree_vpago 2.3.5.pre.pre.pre.8 → 2.3.7.pre.pre1
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/Gemfile.lock +1 -1
- data/app/controllers/spree/admin/payments_controller_decorator.rb +47 -1
- data/app/controllers/spree/admin/suspicious_orders_controller.rb +64 -0
- data/app/models/vpago/order_decorator.rb +6 -0
- data/app/models/vpago/payment_decorator.rb +4 -2
- data/app/overrides/spree/admin/payments/_form/admin_payment_form_fields.html.erb.deface +36 -0
- data/app/overrides/spree/admin/payments/_list/actions.html.erb.deface +3 -1
- data/app/overrides/spree/admin/shared/sub_menu/_orders/suspicious_orders.html.erb.deface +3 -0
- data/app/views/spree/admin/suspicious_orders/_payments_table.html.erb +71 -0
- data/app/views/spree/admin/suspicious_orders/index.html.erb +112 -0
- data/app/views/spree/admin/suspicious_orders/payments.html.erb +3 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/km.yml +11 -0
- data/config/routes.rb +7 -0
- data/lib/spree_vpago/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9111b222dfcb967061ca1a6b19df5e171897bc74eaef45bc3a1a0a986214024
|
|
4
|
+
data.tar.gz: 8085228fc934b882f6de0177fe7c9e6d44237a193664d314d19f6fbaa5b03a08
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2c8fb4987db12fb7a40e8589023c500294efdcfffe5842c5c2ab6a651475e7a59accdbc62ae75be318edfbd8498a33a59f77adbf3bab96a6e17c483881fb60ab
|
|
7
|
+
data.tar.gz: 2d9e40a576de3be20a53e6c7db445f315edbf081c7807d5672e3ec1370d91a6ac19597f876fd698d1e061cf4f4b61f917787c95163335891581ff527d6acd18c
|
data/Gemfile.lock
CHANGED
|
@@ -9,9 +9,55 @@ module Spree
|
|
|
9
9
|
payment_method ||= Spree::PaymentMethod.find(params[:payment][:payment_method_id])
|
|
10
10
|
return unless payment_method.vpago_payment?
|
|
11
11
|
|
|
12
|
-
source_params = { payment_option: payment_method.preferred_payment_option }
|
|
12
|
+
source_params = { payment_option: payment_method.try(:preferred_payment_option) }
|
|
13
13
|
params[:payment][:source_attributes] = source_params
|
|
14
14
|
end
|
|
15
|
+
|
|
16
|
+
# override
|
|
17
|
+
# For vpago gateways created from the admin backend, we skip immediate processing
|
|
18
|
+
# and keep the payment in `checkout` state so the admin can open the QR checkout
|
|
19
|
+
# URL and pay on behalf of the customer. The bank webhook
|
|
20
|
+
# (process_payment -> Vpago::PaymentProcessorJob) completes the order once paid.
|
|
21
|
+
def create
|
|
22
|
+
return super unless @payment_method&.vpago_payment?
|
|
23
|
+
|
|
24
|
+
invoke_callbacks(:create, :before)
|
|
25
|
+
|
|
26
|
+
@payment = @order.payments.build(object_params)
|
|
27
|
+
|
|
28
|
+
if @payment.save
|
|
29
|
+
invoke_callbacks(:create, :after)
|
|
30
|
+
flash[:success] = flash_message_for(@payment, :successfully_created)
|
|
31
|
+
redirect_to spree.admin_order_payments_path(@order)
|
|
32
|
+
else
|
|
33
|
+
invoke_callbacks(:create, :fails)
|
|
34
|
+
flash[:error] = Spree.t(:payment_could_not_be_created)
|
|
35
|
+
render :new, status: :unprocessable_entity
|
|
36
|
+
end
|
|
37
|
+
rescue Spree::Core::GatewayError => e
|
|
38
|
+
invoke_callbacks(:create, :fails)
|
|
39
|
+
flash[:error] = e.message.to_s
|
|
40
|
+
redirect_to spree.new_admin_order_payment_path(@order)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# override
|
|
44
|
+
# Before the normal `process!` re-runs the gateway, reset a stuck vpago
|
|
45
|
+
# payment back to `checkout`. Admin reprocess only — the automatic webhook
|
|
46
|
+
# path is untouched (it auto-resets `failed` alone).
|
|
47
|
+
def fire
|
|
48
|
+
reset_stuck_payment_for_reprocess!
|
|
49
|
+
super
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def reset_stuck_payment_for_reprocess!
|
|
55
|
+
return unless params[:e] == 'process'
|
|
56
|
+
return unless @payment&.payment_method&.vpago_payment?
|
|
57
|
+
return unless @payment.can_reset_for_retry?
|
|
58
|
+
|
|
59
|
+
@payment.reset_for_retry!
|
|
60
|
+
end
|
|
15
61
|
end
|
|
16
62
|
end
|
|
17
63
|
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Admin
|
|
3
|
+
class SuspiciousOrdersController < Spree::Admin::BaseController
|
|
4
|
+
around_action :set_writing_role, only: %i[check_transaction]
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
params[:q] = { completed_at_not_null: 1, payment_state_eq: 'balance_due', s: 'completed_at desc' }.dup if params[:q].blank?
|
|
8
|
+
|
|
9
|
+
@search = scope.ransack(params[:q])
|
|
10
|
+
@orders = @search.result(distinct: true)
|
|
11
|
+
.preload(:payments, :reimbursements)
|
|
12
|
+
.page(params[:page])
|
|
13
|
+
.per(params[:per_page] || Spree::Backend::Config[:admin_orders_per_page])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def payments
|
|
17
|
+
@order = scope.find_by!(number: params[:id])
|
|
18
|
+
@payments = @order.payments.includes(:payment_method)
|
|
19
|
+
|
|
20
|
+
render layout: false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Renders the result inline into this order's payments frame instead of
|
|
24
|
+
# redirecting, so the admin never leaves this list.
|
|
25
|
+
def check_transaction
|
|
26
|
+
@order = scope.find_by!(number: params[:id])
|
|
27
|
+
payment = @order.payments.find_by!(number: params[:payment_number])
|
|
28
|
+
|
|
29
|
+
@check_result = query_payment_transaction(payment)
|
|
30
|
+
@payments = @order.payments.includes(:payment_method)
|
|
31
|
+
|
|
32
|
+
render 'payments', layout: false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Delegates to the gateway's own check_transaction (same method
|
|
38
|
+
# PaywayV2/Vattanac/TrueMoney already implement) - no per-gateway
|
|
39
|
+
# branching needed here.
|
|
40
|
+
def query_payment_transaction(payment)
|
|
41
|
+
method = payment.payment_method
|
|
42
|
+
return nil unless method.support_check_transaction_api?
|
|
43
|
+
|
|
44
|
+
result = method.check_transaction(payment)
|
|
45
|
+
|
|
46
|
+
# Not every gateway's checker implements error_message (e.g. Vattanac,
|
|
47
|
+
# TrueMoney) - fall back to the raw response so this doesn't blow up
|
|
48
|
+
# for gateways that only implement the minimal success?/json_response duck type.
|
|
49
|
+
message =
|
|
50
|
+
if result.success?
|
|
51
|
+
Spree.t('vpago.payments.payment_found_with_result', result: result.try(:json_response))
|
|
52
|
+
else
|
|
53
|
+
Spree.t('vpago.payments.payment_not_found_with_error', error: result.try(:error_message) || result.try(:json_response))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
{ success: result.success?, message: message }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def scope
|
|
60
|
+
current_store.orders.accessible_by(current_ability, :index)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -64,6 +64,8 @@ module Vpago
|
|
|
64
64
|
|
|
65
65
|
payment_methods = if early_adopter?
|
|
66
66
|
payment_methods.available_on_frontend_for_early_adopter.select { |pm| pm.available_for_order?(self) }
|
|
67
|
+
elsif ticket_seller?
|
|
68
|
+
payment_methods.available_on_back_end.select { |pm| pm.available_for_order?(self) }
|
|
67
69
|
else
|
|
68
70
|
payment_methods.available_on_front_end.select { |pm| pm.available_for_order?(self) }
|
|
69
71
|
end
|
|
@@ -90,6 +92,10 @@ module Vpago
|
|
|
90
92
|
user.present? && user.respond_to?(:early_adopter?) && user.early_adopter?
|
|
91
93
|
end
|
|
92
94
|
|
|
95
|
+
def ticket_seller?
|
|
96
|
+
user.present? && user.respond_to?(:has_spree_role?) && user.has_spree_role?('ticket_seller')
|
|
97
|
+
end
|
|
98
|
+
|
|
93
99
|
def tenant_payment_methods
|
|
94
100
|
tenant.tenant_payment_methods
|
|
95
101
|
end
|
|
@@ -27,9 +27,11 @@ module Vpago
|
|
|
27
27
|
:process_payment_url,
|
|
28
28
|
to: :url_constructor
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# State machine event for payment retry / admin reprocess.
|
|
31
|
+
# `failed` is auto-reset by process!/capture! below (Sidekiq retry);
|
|
32
|
+
# void/invalid/processing are reset only by the admin reprocess action.
|
|
31
33
|
base.state_machine.event :reset_for_retry do
|
|
32
|
-
transition from: %i[failed], to: :checkout
|
|
34
|
+
transition from: %i[failed void invalid processing], to: :checkout
|
|
33
35
|
end
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!-- replace "[data-hook='admin_payment_form_fields']" -->
|
|
2
|
+
|
|
3
|
+
<div data-hook="admin_payment_form_fields">
|
|
4
|
+
<div class="form-group">
|
|
5
|
+
<%= f.label :amount, Spree.t(:amount) %>
|
|
6
|
+
<%= f.text_field :amount, value: @order.display_outstanding_balance.money, class: 'form-control' %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="form-group">
|
|
9
|
+
<strong><%= Spree.t(:payment_method) %></strong>
|
|
10
|
+
<% @payment_methods.each do |method| %>
|
|
11
|
+
<div class="radio" data-id="<%= Spree.t(method.name, scope: :payment_methods, default: method.name).parameterize %>">
|
|
12
|
+
<label data-hook="payment_method_field">
|
|
13
|
+
<%= radio_button_tag 'payment[payment_method_id]', method.id, method == @payment_method, { class: "payment_methods_radios" } %>
|
|
14
|
+
<%= Spree.t(method.name, scope: :payment_methods, default: method.name) %>
|
|
15
|
+
</label>
|
|
16
|
+
</div>
|
|
17
|
+
<% end %>
|
|
18
|
+
|
|
19
|
+
<div class="payment-method-settings">
|
|
20
|
+
<% @payment_methods.each do |method| %>
|
|
21
|
+
<div class="payment-methods my-3" id="payment_method_<%= method.id %>">
|
|
22
|
+
<% if method.source_required? %>
|
|
23
|
+
<% partial_path = "spree/admin/payments/source_forms/#{method.method_type}" %>
|
|
24
|
+
<% if lookup_context.exists?(partial_path, [], true) %>
|
|
25
|
+
<%= render partial: partial_path,
|
|
26
|
+
locals: {
|
|
27
|
+
payment_method: method,
|
|
28
|
+
previous_cards: method.reusable_sources(@order)
|
|
29
|
+
} %>
|
|
30
|
+
<% end %>
|
|
31
|
+
<% end %>
|
|
32
|
+
</div>
|
|
33
|
+
<% end %>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
<% elsif action == 'open_checkout' %>
|
|
8
8
|
<%= link_to_with_icon('qr-code.svg', Spree.t(action), payment.checkout_url, target: '_blank', no_text: true, class: "btn btn-light btn-sm") %>
|
|
9
9
|
<% else %>
|
|
10
|
-
|
|
10
|
+
<% action_data = { action: action } %>
|
|
11
|
+
<% action_data[:confirm] = Spree.t(:reprocess_payment_confirmation, default: 'Reprocess this payment? This will re-run the gateway transaction.') if action == 'process' %>
|
|
12
|
+
<%= link_to_with_icon(action + '.svg', Spree.t(action), fire_admin_order_payment_path(@order, payment, e: action), method: :put, no_text: true, data: action_data, class: "btn btn-light btn-sm") if can?(action.to_sym, payment) %>
|
|
11
13
|
<% end %>
|
|
12
14
|
<% end %>
|
|
13
15
|
</span>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<% if check_result.present? %>
|
|
2
|
+
<script>
|
|
3
|
+
show_flash('<%= check_result[:success] ? "success" : "error" %>', '<%= j check_result[:message] %>')
|
|
4
|
+
</script>
|
|
5
|
+
<% end %>
|
|
6
|
+
|
|
7
|
+
<table class="table mb-0">
|
|
8
|
+
<thead class="text-muted">
|
|
9
|
+
<tr>
|
|
10
|
+
<th><%= Spree::Payment.human_attribute_name(:id) %></th>
|
|
11
|
+
<th><%= Spree::Payment.human_attribute_name(:number) %></th>
|
|
12
|
+
<th><%= "#{Spree.t('date')}/#{Spree.t('time')}" %></th>
|
|
13
|
+
<th class="text-center"><%= Spree.t(:amount) %></th>
|
|
14
|
+
<th class="text-center"><%= Spree.t(:payment_method) %></th>
|
|
15
|
+
<th class="text-center"><%= Spree.t(:payment_state) %></th>
|
|
16
|
+
<th class="actions text-center"></th>
|
|
17
|
+
</tr>
|
|
18
|
+
</thead>
|
|
19
|
+
<tbody>
|
|
20
|
+
<% payments.each do |payment| %>
|
|
21
|
+
<tr>
|
|
22
|
+
<td><%= payment.id %></td>
|
|
23
|
+
<td><%= link_to payment.number, spree.admin_order_payment_path(order, payment), data: { turbo_frame: '_top' } %></td>
|
|
24
|
+
<td><%= pretty_time(payment.created_at) %></td>
|
|
25
|
+
<td class="text-center"><%= payment.display_amount %></td>
|
|
26
|
+
<td class="text-center">
|
|
27
|
+
<% payment_method = payment.payment_method %>
|
|
28
|
+
<% if can?(:update, payment_method) %>
|
|
29
|
+
<%= link_to payment_method.name, spree.edit_admin_payment_method_path(payment_method),
|
|
30
|
+
target: '_blank', rel: 'noopener noreferrer' %>
|
|
31
|
+
<% else %>
|
|
32
|
+
<%= payment_method.name %>
|
|
33
|
+
<% end %>
|
|
34
|
+
</td>
|
|
35
|
+
<td class="text-center">
|
|
36
|
+
<span class="badge badge-pill badge-<%= payment.state %>">
|
|
37
|
+
<%= Spree.t(payment.state, scope: :payment_states, default: payment.state.capitalize) %>
|
|
38
|
+
</span>
|
|
39
|
+
</td>
|
|
40
|
+
<td class="actions">
|
|
41
|
+
<span class="d-flex justify-content-center payment-action-buttons">
|
|
42
|
+
<% if payment.payment_method.support_check_transaction_api? %>
|
|
43
|
+
|
|
44
|
+
<%= button_to spree.check_transaction_admin_suspicious_order_path(order, payment_number: payment.number),
|
|
45
|
+
form: { data: { turbo_frame: "suspicious_order_#{order.id}_payments" }, class: 'd-inline' },
|
|
46
|
+
class: 'btn btn-light btn-sm icon-link with-tip', title: Spree.t('vpago.payments.query_status') do %>
|
|
47
|
+
<%= svg_icon(name: 'search.svg', classes: 'icon icon-search', width: 14, height: 14) %>
|
|
48
|
+
<% end %>
|
|
49
|
+
<% end %>
|
|
50
|
+
|
|
51
|
+
<% payment.actions.each do |action| %>
|
|
52
|
+
<% if action == 'credit' %>
|
|
53
|
+
<%= link_to_with_icon('exit.svg', Spree.t(:refund), spree.new_admin_order_payment_refund_path(order, payment),
|
|
54
|
+
no_text: true, data: { turbo_frame: '_top' }, class: 'btn btn-light btn-sm') if can?(:create, Spree::Refund) %>
|
|
55
|
+
<% elsif action == 'open_checkout' %>
|
|
56
|
+
<%= link_to_with_icon('qr-code.svg', Spree.t(action), payment.checkout_url,
|
|
57
|
+
target: '_blank', rel: 'noopener noreferrer', no_text: true, class: 'btn btn-light btn-sm') %>
|
|
58
|
+
<% else %>
|
|
59
|
+
<% action_data = { action: action, turbo_frame: '_top' } %>
|
|
60
|
+
<% action_data[:confirm] = Spree.t(:reprocess_payment_confirmation, default: 'Reprocess this payment? This will re-run the gateway transaction.') if action == 'process' %>
|
|
61
|
+
<%= link_to_with_icon(action + '.svg', Spree.t(action), spree.fire_admin_order_payment_path(order, payment, e: action),
|
|
62
|
+
method: :put, no_text: true, data: action_data,
|
|
63
|
+
class: 'btn btn-light btn-sm') if can?(action.to_sym, payment) %>
|
|
64
|
+
<% end %>
|
|
65
|
+
<% end %>
|
|
66
|
+
</span>
|
|
67
|
+
</td>
|
|
68
|
+
</tr>
|
|
69
|
+
<% end %>
|
|
70
|
+
</tbody>
|
|
71
|
+
</table>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<% content_for :page_title do %>
|
|
2
|
+
<%= Spree.t('admin.orders.suspicious_orders') %>
|
|
3
|
+
<% end %>
|
|
4
|
+
|
|
5
|
+
<%# Simple, always-visible filters kept intentionally small. %>
|
|
6
|
+
<div class="card mb-3">
|
|
7
|
+
<div class="card-body">
|
|
8
|
+
<%= search_form_for [:admin, @search], url: spree.admin_suspicious_orders_path, html: { method: :get } do |f| %>
|
|
9
|
+
<div class="form-row align-items-end">
|
|
10
|
+
<div class="col-12 col-sm-6 col-lg mb-2 mb-lg-0">
|
|
11
|
+
<div class="form-group mb-0">
|
|
12
|
+
<%= f.label :number_cont, Spree.t(:search_order_number) %>
|
|
13
|
+
<%= f.search_field :number_cont, class: 'form-control' %>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="col-12 col-sm-6 col-lg mb-2 mb-lg-0">
|
|
17
|
+
<div class="form-group mb-0">
|
|
18
|
+
<%= f.label :payments_number_cont, Spree.t('admin.orders.payment_number') %>
|
|
19
|
+
<%= f.search_field :payments_number_cont, class: 'form-control' %>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="col-12 col-sm-6 col-lg mb-2 mb-lg-0">
|
|
23
|
+
<div class="form-group mb-0">
|
|
24
|
+
<%= f.label :email_or_phone_number_cont, Spree.t('admin.orders.email_or_phone') %>
|
|
25
|
+
<%= f.search_field :email_or_phone_number_cont, class: 'form-control' %>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="col-12 col-sm-6 col-lg mb-2 mb-lg-0">
|
|
29
|
+
<div class="form-group mb-0">
|
|
30
|
+
<%= f.label :payment_state_eq, Spree.t(:payment_state) %>
|
|
31
|
+
|
|
32
|
+
<%= f.select :payment_state_eq,
|
|
33
|
+
::Spree::Order::PAYMENT_STATES.map { |s| [Spree.t("payment_states.#{s}"), s] },
|
|
34
|
+
{ include_blank: true }, class: 'select2-clear' %>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="col-12 col-sm-6 col-lg mb-2 mb-lg-0">
|
|
38
|
+
<div class="form-group mb-0">
|
|
39
|
+
<%= f.label :payments_payment_method_id_eq, Spree.t(:payment_method) %>
|
|
40
|
+
<%= f.select :payments_payment_method_id_eq,
|
|
41
|
+
::Spree::PaymentMethod.pluck(:name, :id),
|
|
42
|
+
{ include_blank: true }, class: 'select2-clear' %>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="col-12 col-lg-auto mb-2 mb-lg-0">
|
|
46
|
+
<%= button Spree.t(:search), 'search.svg', 'submit', class: 'btn-primary btn-block' %>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
<% end %>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<table class="table" id="listing_suspicious_orders">
|
|
54
|
+
<thead>
|
|
55
|
+
<tr>
|
|
56
|
+
<th><%= Spree.t(:order) %></th>
|
|
57
|
+
<th><%= Spree.t(:date) %></th>
|
|
58
|
+
<th><%= Spree.t(:status) %></th>
|
|
59
|
+
<th><%= Spree.t(:payment_state) %></th>
|
|
60
|
+
<th class="text-right"><%= Spree.t(:total) %></th>
|
|
61
|
+
<th class="text-right"><%= Spree.t('admin.orders.outstanding_balance') %></th>
|
|
62
|
+
<th class="text-right"><%= Spree.t('admin.orders.payments') %></th>
|
|
63
|
+
</tr>
|
|
64
|
+
</thead>
|
|
65
|
+
<tbody>
|
|
66
|
+
<% @orders.each do |order| %>
|
|
67
|
+
<% payments_frame_id = "payments-collapse-#{order.id}" %>
|
|
68
|
+
<tr>
|
|
69
|
+
<td><%= link_to order.number, spree.edit_admin_order_path(order) %></td>
|
|
70
|
+
<td><%= pretty_time(order.completed_at) %></td>
|
|
71
|
+
<td>
|
|
72
|
+
<span class="badge badge-pill badge-<%= order.state %>">
|
|
73
|
+
<%= Spree.t("order_state.#{order.state}") %>
|
|
74
|
+
</span>
|
|
75
|
+
</td>
|
|
76
|
+
<td>
|
|
77
|
+
<span class="badge badge-pill badge-<%= order.payment_state %>">
|
|
78
|
+
<%= Spree.t("payment_states.#{order.payment_state}") %>
|
|
79
|
+
</span>
|
|
80
|
+
</td>
|
|
81
|
+
<td class="text-right"><%= order.display_total %></td>
|
|
82
|
+
<td class="text-right"><%= order.display_outstanding_balance %></td>
|
|
83
|
+
<td class="text-right">
|
|
84
|
+
<button type="button" data-toggle="collapse" data-target="#<%= payments_frame_id %>"
|
|
85
|
+
aria-expanded="false" aria-controls="<%= payments_frame_id %>"
|
|
86
|
+
class="btn btn-sm btn-light">
|
|
87
|
+
<%= Spree.t('admin.orders.payments_count', count: order.payments.size) %>
|
|
88
|
+
<%= svg_icon(name: 'chevron-down.svg', classes: 'icon ml-1', width: 12, height: 12) %>
|
|
89
|
+
</button>
|
|
90
|
+
</td>
|
|
91
|
+
</tr>
|
|
92
|
+
<tr>
|
|
93
|
+
<td colspan="7" class="p-0 border-top-0">
|
|
94
|
+
<div class="collapse" id="<%= payments_frame_id %>">
|
|
95
|
+
<div class="mb-3 border border-primary rounded-lg overflow-hidden bg-white">
|
|
96
|
+
<div class="bg-light px-3 py-2 small font-weight-bold text-uppercase text-muted">
|
|
97
|
+
<%= svg_icon(name: 'receipt.svg', classes: 'icon mr-2', width: 14, height: 14) %>
|
|
98
|
+
<%= Spree.t('admin.orders.payments_for_order', number: order.number) %>
|
|
99
|
+
</div>
|
|
100
|
+
<%= turbo_frame_tag "suspicious_order_#{order.id}_payments",
|
|
101
|
+
src: spree.payments_admin_suspicious_order_path(order), loading: 'lazy' do %>
|
|
102
|
+
<div class="p-3 text-center text-muted"><%= Spree.t(:loading) %>…</div>
|
|
103
|
+
<% end %>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</td>
|
|
107
|
+
</tr>
|
|
108
|
+
<% end %>
|
|
109
|
+
</tbody>
|
|
110
|
+
</table>
|
|
111
|
+
|
|
112
|
+
<%= render 'spree/admin/shared/index_table_options', collection: @orders %>
|
data/config/locales/en.yml
CHANGED
|
@@ -10,6 +10,17 @@ en:
|
|
|
10
10
|
insufficient_payment_amount_to_cover_the_total: "Payment amount is insufficient to cover the total"
|
|
11
11
|
qr_code: "QR code"
|
|
12
12
|
open_checkout: "Open Checkout"
|
|
13
|
+
admin:
|
|
14
|
+
orders:
|
|
15
|
+
suspicious_orders: "Suspicious Orders"
|
|
16
|
+
outstanding_balance: "Outstanding Balance"
|
|
17
|
+
payments: "Payments"
|
|
18
|
+
payment_number: "Payment Number"
|
|
19
|
+
email_or_phone: "Email / Phone Number"
|
|
20
|
+
payments_count:
|
|
21
|
+
one: "1 Payment"
|
|
22
|
+
other: "%{count} Payments"
|
|
23
|
+
payments_for_order: "Payments for %{number}"
|
|
13
24
|
vpago:
|
|
14
25
|
payments:
|
|
15
26
|
check_and_heal: "Auto correct"
|
data/config/locales/km.yml
CHANGED
|
@@ -6,6 +6,17 @@ spree:
|
|
|
6
6
|
insufficient_payment_amount_to_cover_the_total: "ចំនួនទឹកប្រាក់នៃការទូទាត់គឺមិនគ្រប់គ្រាន់"
|
|
7
7
|
qr_code: "QR code"
|
|
8
8
|
open_checkout: "Open Checkout"
|
|
9
|
+
admin:
|
|
10
|
+
orders:
|
|
11
|
+
suspicious_orders: "ការបង់ប្រាក់គួរឱ្យសង្ស័យ"
|
|
12
|
+
outstanding_balance: "សមតុល្យនៅសល់"
|
|
13
|
+
payments: "ការបង់ប្រាក់"
|
|
14
|
+
payment_number: "លេខការបង់ប្រាក់"
|
|
15
|
+
email_or_phone: "អ៊ីមែល / លេខទូរស័ព្ទ"
|
|
16
|
+
payments_count:
|
|
17
|
+
one: "ការបង់ប្រាក់ %{count}"
|
|
18
|
+
other: "ការបង់ប្រាក់ %{count}"
|
|
19
|
+
payments_for_order: "ការបង់ប្រាក់សម្រាប់ %{number}"
|
|
9
20
|
vpago:
|
|
10
21
|
payments:
|
|
11
22
|
check_and_heal: "កែស្វ័យប្រវត្តិ"
|
data/config/routes.rb
CHANGED
|
@@ -90,5 +90,12 @@ Spree::Core::Engine.add_routes do
|
|
|
90
90
|
post :verify_with_bank
|
|
91
91
|
end
|
|
92
92
|
end
|
|
93
|
+
|
|
94
|
+
resources :suspicious_orders, only: [:index] do
|
|
95
|
+
member do
|
|
96
|
+
get :payments
|
|
97
|
+
post 'payments/:payment_number/check_transaction', action: :check_transaction, as: :check_transaction
|
|
98
|
+
end
|
|
99
|
+
end
|
|
93
100
|
end
|
|
94
101
|
end
|
data/lib/spree_vpago/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_vpago
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.3.
|
|
4
|
+
version: 2.3.7.pre.pre1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- You
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -165,6 +165,7 @@ files:
|
|
|
165
165
|
- app/controllers/spree/admin/payout_profile_shipping_methods_controller.rb
|
|
166
166
|
- app/controllers/spree/admin/payout_profiles_controller.rb
|
|
167
167
|
- app/controllers/spree/admin/payouts_controller.rb
|
|
168
|
+
- app/controllers/spree/admin/suspicious_orders_controller.rb
|
|
168
169
|
- app/controllers/spree/api/v2/storefront/checkout_controller_decorator.rb
|
|
169
170
|
- app/controllers/spree/payway_card_popups_controller.rb
|
|
170
171
|
- app/controllers/spree/payway_results_controller.rb
|
|
@@ -237,11 +238,13 @@ files:
|
|
|
237
238
|
- app/overrides/spree/admin/payment_methods/index/tenant_header.html.erb.deface
|
|
238
239
|
- app/overrides/spree/admin/payment_methods/index/vendor_body.html.erb.deface
|
|
239
240
|
- app/overrides/spree/admin/payment_methods/index/vendor_header.html.erb.deface
|
|
241
|
+
- app/overrides/spree/admin/payments/_form/admin_payment_form_fields.html.erb.deface
|
|
240
242
|
- app/overrides/spree/admin/payments/_list/actions.html.erb.deface
|
|
241
243
|
- app/overrides/spree/admin/promotions/_promotion_action/run_by_field.html.erb.deface
|
|
242
244
|
- app/overrides/spree/admin/shared/_order_tabs/payouts.html.erb.deface
|
|
243
245
|
- app/overrides/spree/admin/shared/_product_tabs/payout_profile_products.html.erb.deface
|
|
244
246
|
- app/overrides/spree/admin/shared/sub_menu/_integrations/payout_profiles.html.erb.deface
|
|
247
|
+
- app/overrides/spree/admin/shared/sub_menu/_orders/suspicious_orders.html.erb.deface
|
|
245
248
|
- app/overrides/spree/admin/shipping_methods/_form/handle_by.html.erb.deface
|
|
246
249
|
- app/overrides/spree/admin/shipping_methods/edit/shipping_method_tabs.html.erb.deface
|
|
247
250
|
- app/overrides/spree/admin/tax_categories/_form/collect_by_field.html.erb.deface
|
|
@@ -308,6 +311,9 @@ files:
|
|
|
308
311
|
- app/views/spree/admin/shared/_shipping_method_tabs.html.erb
|
|
309
312
|
- app/views/spree/admin/shared/payout_profile/_info_card.html.erb
|
|
310
313
|
- app/views/spree/admin/shared/payout_profile/_status.html.erb
|
|
314
|
+
- app/views/spree/admin/suspicious_orders/_payments_table.html.erb
|
|
315
|
+
- app/views/spree/admin/suspicious_orders/index.html.erb
|
|
316
|
+
- app/views/spree/admin/suspicious_orders/payments.html.erb
|
|
311
317
|
- app/views/spree/checkout/payment/_acleda.html.erb
|
|
312
318
|
- app/views/spree/checkout/payment/_acleda_checkout_form.html.erb
|
|
313
319
|
- app/views/spree/checkout/payment/_acleda_mobile.html.erb
|