spree_vpago 2.1.7 → 2.1.9.pre.add.pre.payment.pre.processor.pre.job.pre.logging
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 +6 -6
- data/app/controllers/spree/vpago_payments_controller.rb +50 -6
- data/app/controllers/spree/webhook/payways_controller.rb +5 -3
- data/app/jobs/vpago/payment_processor_job.rb +43 -0
- data/app/lib/vpago/timing_helper.rb +21 -0
- data/app/models/spree/payment_method/cash_on.rb +15 -0
- data/app/models/vpago/order_decorator.rb +5 -2
- data/app/models/vpago/payment_method_decorator.rb +7 -1
- data/lib/spree_vpago/engine.rb +2 -1
- data/lib/spree_vpago/version.rb +1 -1
- data/lib/vpago/payway_v2/base.rb +5 -0
- data/lib/vpago/payway_v2/checkout.rb +1 -0
- data/lib/vpago/payway_v2/transaction_status.rb +30 -1
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08625418c07e62cfb023d294ccbb6347eef32d80185a062e998c2ff60f40384c'
|
|
4
|
+
data.tar.gz: 7cb7085798844c5e0f1c988c4d003f8b98c37a484b0cc21b2136b18168be2b17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db274532d60f50158835effe14fb965fbe038a717314a24cdb3ac7596c90b32d01aa3a44780596233891f27c56d5cec75a97a0cbaefec8db26cde761b8d11050
|
|
7
|
+
data.tar.gz: 2385401f1b371a5d4ad19b33c02dce9f2f3b1a0cd92b1366b23887b6e3d6ff225f285e29e5143bf3eae69cf7ae6e1fcaa854eb6a732c5cff13a5c04a21f350ce
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
spree_vpago (2.1.
|
|
4
|
+
spree_vpago (2.1.9.pre.add.pre.payment.pre.processor.pre.job.pre.logging)
|
|
5
5
|
faraday
|
|
6
6
|
google-cloud-firestore
|
|
7
7
|
spree_api (>= 4.5)
|
|
@@ -128,7 +128,7 @@ GEM
|
|
|
128
128
|
babel-source (>= 4.0, < 6)
|
|
129
129
|
execjs (~> 2.0)
|
|
130
130
|
base64 (0.3.0)
|
|
131
|
-
bcrypt (3.1.
|
|
131
|
+
bcrypt (3.1.21)
|
|
132
132
|
bigdecimal (3.1.8)
|
|
133
133
|
bootstrap (4.6.2.1)
|
|
134
134
|
autoprefixer-rails (>= 9.1.0)
|
|
@@ -188,7 +188,7 @@ GEM
|
|
|
188
188
|
faraday-http-cache (2.5.0)
|
|
189
189
|
faraday (>= 0.8)
|
|
190
190
|
faraday-net_http (3.0.2)
|
|
191
|
-
faraday-retry (2.
|
|
191
|
+
faraday-retry (2.4.0)
|
|
192
192
|
faraday (~> 2.0)
|
|
193
193
|
ffaker (2.21.0)
|
|
194
194
|
ffi (1.15.5)
|
|
@@ -234,7 +234,7 @@ GEM
|
|
|
234
234
|
google-cloud-core (~> 1.7)
|
|
235
235
|
google-cloud-firestore-v1 (~> 2.0)
|
|
236
236
|
rbtree (~> 0.4.2)
|
|
237
|
-
google-cloud-firestore-v1 (2.
|
|
237
|
+
google-cloud-firestore-v1 (2.3.0)
|
|
238
238
|
gapic-common (~> 1.2)
|
|
239
239
|
google-cloud-errors (~> 1.0)
|
|
240
240
|
google-cloud-location (~> 1.0)
|
|
@@ -242,7 +242,7 @@ GEM
|
|
|
242
242
|
gapic-common (~> 1.2)
|
|
243
243
|
google-cloud-errors (~> 1.0)
|
|
244
244
|
google-logging-utils (0.2.0)
|
|
245
|
-
google-protobuf (4.33.
|
|
245
|
+
google-protobuf (4.33.4)
|
|
246
246
|
bigdecimal
|
|
247
247
|
rake (>= 13)
|
|
248
248
|
googleapis-common-protos (1.9.0)
|
|
@@ -251,7 +251,7 @@ GEM
|
|
|
251
251
|
grpc (~> 1.41)
|
|
252
252
|
googleapis-common-protos-types (1.22.0)
|
|
253
253
|
google-protobuf (~> 4.26)
|
|
254
|
-
googleauth (1.16.
|
|
254
|
+
googleauth (1.16.1)
|
|
255
255
|
faraday (>= 1.0, < 3.a)
|
|
256
256
|
google-cloud-env (~> 2.2)
|
|
257
257
|
google-logging-utils (~> 0.1)
|
|
@@ -44,14 +44,15 @@ module Spree
|
|
|
44
44
|
return render_not_found unless @payment.present?
|
|
45
45
|
|
|
46
46
|
unless @payment.order.paid?
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
enqueued_at = Time.now.to_f
|
|
48
|
+
log_enqueue_start(@payment, enqueued_at, return_params)
|
|
49
|
+
|
|
50
|
+
Vpago::PaymentProcessorJob.perform_later(payment_number: @payment.number, enqueued_at: enqueued_at)
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
render json: { status: :ok }, status: :ok
|
|
53
54
|
rescue StandardError => e
|
|
54
|
-
|
|
55
|
+
log_enqueue_error(e)
|
|
55
56
|
render json: { status: :internal_server_error, message: 'Failed to enqueue payment processor job' }, status: :internal_server_error
|
|
56
57
|
end
|
|
57
58
|
|
|
@@ -62,14 +63,21 @@ module Spree
|
|
|
62
63
|
@payment = Spree::Payment.find_by(number: params.dig(:data, :external_ref_id))
|
|
63
64
|
return render_not_found unless @payment
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
unless @payment.order.paid?
|
|
67
|
+
enqueued_at = Time.now.to_f
|
|
68
|
+
log_enqueue_start(@payment, enqueued_at)
|
|
69
|
+
|
|
70
|
+
Vpago::PaymentProcessorJob.perform_later(payment_number: @payment.number, enqueued_at: enqueued_at)
|
|
71
|
+
end
|
|
66
72
|
|
|
67
73
|
render json: { status: { code: '000001', message: 'success' }, data: nil }, status: :ok
|
|
68
74
|
rescue StandardError => e
|
|
69
|
-
|
|
75
|
+
log_enqueue_error(e)
|
|
70
76
|
render json: { status: :internal_server_error, message: 'Failed to enqueue payment processor job' }, status: :internal_server_error
|
|
71
77
|
end
|
|
72
78
|
|
|
79
|
+
private
|
|
80
|
+
|
|
73
81
|
def sanitize_return_params
|
|
74
82
|
sanitized_params = params.permit!.to_h
|
|
75
83
|
|
|
@@ -92,5 +100,41 @@ module Spree
|
|
|
92
100
|
format.json { render json: { status: :unauthorized }, status: :unauthorized }
|
|
93
101
|
end
|
|
94
102
|
end
|
|
103
|
+
|
|
104
|
+
def log_enqueue_start(payment, enqueued_at, return_params = {})
|
|
105
|
+
Rails.logger.info(
|
|
106
|
+
{
|
|
107
|
+
event: 'vpago.payment_processor_job.enqueue',
|
|
108
|
+
payment_number: payment.number,
|
|
109
|
+
order_number: payment.order&.number,
|
|
110
|
+
request_id: request.request_id,
|
|
111
|
+
payment_method_type: payment.payment_method&.type,
|
|
112
|
+
payment_method_name: payment.payment_method&.name,
|
|
113
|
+
gateway: detect_payway_gateway_version(payment.payment_method),
|
|
114
|
+
tran_id: (return_params[:tran_id] || return_params['tran_id']),
|
|
115
|
+
enqueued_at: enqueued_at
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def log_enqueue_error(error)
|
|
121
|
+
Rails.logger.error(
|
|
122
|
+
{
|
|
123
|
+
event: 'vpago.payment_processor_job.enqueue.error',
|
|
124
|
+
request_id: request.request_id,
|
|
125
|
+
payment_number: @payment&.number,
|
|
126
|
+
error_class: error.class.name,
|
|
127
|
+
error_message: error.message
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def detect_payway_gateway_version(payment_method)
|
|
133
|
+
return nil unless payment_method
|
|
134
|
+
return 'payway_v2' if payment_method.type_payway_v2?
|
|
135
|
+
return 'payway_v1' if payment_method.type_payway?
|
|
136
|
+
|
|
137
|
+
nil
|
|
138
|
+
end
|
|
95
139
|
end
|
|
96
140
|
end
|
|
@@ -4,7 +4,7 @@ module Spree
|
|
|
4
4
|
skip_before_action :verify_authenticity_token, only: %i[return v2_return continue v2_continue]
|
|
5
5
|
|
|
6
6
|
# match via: [:get, :post]
|
|
7
|
-
# {"response"=>"{\"tran_id\":\"PE13LXT1\",\"status\":0
|
|
7
|
+
# {"response"=>"{\"tran_id\":\"PE13LXT1\",\"status\":0}"}
|
|
8
8
|
def v2_return
|
|
9
9
|
handler_service = v2_request_updater_service
|
|
10
10
|
|
|
@@ -48,9 +48,11 @@ module Spree
|
|
|
48
48
|
request_updater.call
|
|
49
49
|
|
|
50
50
|
order = payment.order
|
|
51
|
-
order
|
|
51
|
+
order.reload
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
ok = order.paid? || payment.pending?
|
|
54
|
+
|
|
55
|
+
if ok
|
|
54
56
|
render plain: :success
|
|
55
57
|
else
|
|
56
58
|
render plain: :failed, status: 400
|
|
@@ -1,11 +1,54 @@
|
|
|
1
1
|
# Put :payment_processing at a higher priority in your project: config/sidekiq.yml
|
|
2
|
+
require 'vpago/timing_helper'
|
|
3
|
+
|
|
2
4
|
module Vpago
|
|
3
5
|
class PaymentProcessorJob < ::ApplicationUniqueJob
|
|
4
6
|
queue_as :payment_processing
|
|
5
7
|
|
|
6
8
|
def perform(options)
|
|
9
|
+
started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
10
|
+
|
|
11
|
+
enqueued_at = options[:enqueued_at]
|
|
12
|
+
queue_wait_ms = if enqueued_at
|
|
13
|
+
((Time.now.to_f - enqueued_at.to_f) * 1000.0).round(1)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Rails.logger.info(
|
|
17
|
+
{
|
|
18
|
+
event: 'vpago.payment_processor_job.start',
|
|
19
|
+
payment_number: options[:payment_number],
|
|
20
|
+
queue: self.class.queue_name,
|
|
21
|
+
queue_wait_ms: queue_wait_ms
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
|
|
7
25
|
payment = Spree::Payment.find_by!(number: options[:payment_number])
|
|
8
26
|
Vpago::PaymentProcessor.new(payment: payment).call
|
|
27
|
+
|
|
28
|
+
runtime_ms = Vpago::TimingHelper.elapsed_ms(started_at)
|
|
29
|
+
Rails.logger.info(
|
|
30
|
+
{
|
|
31
|
+
event: 'vpago.payment_processor_job.finish',
|
|
32
|
+
payment_number: options[:payment_number],
|
|
33
|
+
queue: self.class.queue_name,
|
|
34
|
+
queue_wait_ms: queue_wait_ms,
|
|
35
|
+
runtime_ms: runtime_ms
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
rescue StandardError => e
|
|
39
|
+
runtime_ms = Vpago::TimingHelper.elapsed_ms(started_at)
|
|
40
|
+
Rails.logger.error(
|
|
41
|
+
{
|
|
42
|
+
event: 'vpago.payment_processor_job.error',
|
|
43
|
+
payment_number: options[:payment_number],
|
|
44
|
+
queue: self.class.queue_name,
|
|
45
|
+
queue_wait_ms: queue_wait_ms,
|
|
46
|
+
runtime_ms: runtime_ms,
|
|
47
|
+
error_class: e.class.name,
|
|
48
|
+
error_message: e.message
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
raise
|
|
9
52
|
end
|
|
10
53
|
end
|
|
11
54
|
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Vpago
|
|
2
|
+
module TimingHelper
|
|
3
|
+
# Measures elapsed time in milliseconds from a given start timestamp.
|
|
4
|
+
#
|
|
5
|
+
# @param started_at [Float] timestamp from Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
6
|
+
# @return [Float] elapsed time in milliseconds, rounded to 1 decimal place
|
|
7
|
+
def self.elapsed_ms(started_at)
|
|
8
|
+
((Process.clock_gettime(Process::CLOCK_MONOTONIC) - started_at) * 1000.0).round(1)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Yields to a block and measures its execution time in milliseconds.
|
|
12
|
+
#
|
|
13
|
+
# @yield the block to measure
|
|
14
|
+
# @return [Float] elapsed time in milliseconds, rounded to 1 decimal place
|
|
15
|
+
def self.measure_ms
|
|
16
|
+
started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
17
|
+
yield
|
|
18
|
+
elapsed_ms(started_at)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -15,10 +15,13 @@ module Vpago
|
|
|
15
15
|
|
|
16
16
|
# override
|
|
17
17
|
def process_payments!
|
|
18
|
-
super
|
|
18
|
+
super
|
|
19
19
|
|
|
20
20
|
# Prevent from reaching :complete state if payment is insufficient
|
|
21
|
-
|
|
21
|
+
return unless insufficient_processed_payment?
|
|
22
|
+
|
|
23
|
+
errors.add(:base, Spree.t(:insufficient_payment_amount_to_cover_the_total))
|
|
24
|
+
false
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def insufficient_processed_payment?
|
|
@@ -8,6 +8,7 @@ module Vpago
|
|
|
8
8
|
TYPE_TRUE_MONEY = 'Spree::Gateway::TrueMoney'.freeze
|
|
9
9
|
TYPE_VATTANAC = 'Spree::Gateway::Vattanac'.freeze
|
|
10
10
|
TYPE_VATTANAC_MINI_APP = 'Spree::Gateway::VattanacMiniApp'.freeze
|
|
11
|
+
TYPE_CASH_ON = 'Spree::PaymentMethod::CashOn'.freeze
|
|
11
12
|
|
|
12
13
|
def self.prepended(base)
|
|
13
14
|
base.preference :icon_name, :string, default: 'cheque'
|
|
@@ -23,7 +24,8 @@ module Vpago
|
|
|
23
24
|
Spree::PaymentMethod::TYPE_ACLEDA_MOBILE,
|
|
24
25
|
Spree::PaymentMethod::TYPE_VATTANAC,
|
|
25
26
|
Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP,
|
|
26
|
-
Spree::PaymentMethod::TYPE_TRUE_MONEY
|
|
27
|
+
Spree::PaymentMethod::TYPE_TRUE_MONEY,
|
|
28
|
+
Spree::PaymentMethod::TYPE_CASH_ON
|
|
27
29
|
]
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -101,6 +103,10 @@ module Vpago
|
|
|
101
103
|
type == Spree::PaymentMethod::TYPE_TRUE_MONEY
|
|
102
104
|
end
|
|
103
105
|
|
|
106
|
+
def type_cash_on?
|
|
107
|
+
type == Spree::PaymentMethod::TYPE_CASH_ON
|
|
108
|
+
end
|
|
109
|
+
|
|
104
110
|
def type_check?
|
|
105
111
|
type == 'Spree::PaymentMethod::Check'
|
|
106
112
|
end
|
data/lib/spree_vpago/engine.rb
CHANGED
data/lib/spree_vpago/version.rb
CHANGED
data/lib/vpago/payway_v2/base.rb
CHANGED
|
@@ -143,6 +143,7 @@ module Vpago
|
|
|
143
143
|
result += return_deeplink if return_deeplink.present?
|
|
144
144
|
result += return_params if return_params.present?
|
|
145
145
|
result += payout if payout.present?
|
|
146
|
+
result += skip_success_page.to_s if skip_success_page.present?
|
|
146
147
|
|
|
147
148
|
log_hash_data = "Hash data: #{result}"
|
|
148
149
|
Rails.logger.info(log_hash_data)
|
|
@@ -154,6 +155,10 @@ module Vpago
|
|
|
154
155
|
payload = { order_number: @payment.order.number, order_id: @payment.order.id }
|
|
155
156
|
JWT.encode(payload, @payment.order.token, 'HS256')
|
|
156
157
|
end
|
|
158
|
+
|
|
159
|
+
def skip_success_page
|
|
160
|
+
1
|
|
161
|
+
end
|
|
157
162
|
end
|
|
158
163
|
end
|
|
159
164
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require 'faraday'
|
|
2
|
+
require 'vpago/timing_helper'
|
|
2
3
|
|
|
3
4
|
module Vpago
|
|
4
5
|
module PaywayV2
|
|
@@ -35,6 +36,8 @@ module Vpago
|
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def check_remote_status
|
|
39
|
+
started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
40
|
+
|
|
38
41
|
conn = Faraday::Connection.new do |faraday|
|
|
39
42
|
faraday.request :url_encoded
|
|
40
43
|
end
|
|
@@ -46,7 +49,33 @@ module Vpago
|
|
|
46
49
|
hash: checker_hmac
|
|
47
50
|
}
|
|
48
51
|
|
|
49
|
-
conn.post(check_transaction_url, data)
|
|
52
|
+
response = conn.post(check_transaction_url, data)
|
|
53
|
+
|
|
54
|
+
runtime_ms = Vpago::TimingHelper.elapsed_ms(started_at)
|
|
55
|
+
Rails.logger.info(
|
|
56
|
+
{
|
|
57
|
+
event: 'vpago.payway.check_transaction',
|
|
58
|
+
version: 'v2',
|
|
59
|
+
payment_number: transaction_id,
|
|
60
|
+
http_status: response.status,
|
|
61
|
+
runtime_ms: runtime_ms
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
response
|
|
66
|
+
rescue StandardError => e
|
|
67
|
+
runtime_ms = Vpago::TimingHelper.elapsed_ms(started_at)
|
|
68
|
+
Rails.logger.error(
|
|
69
|
+
{
|
|
70
|
+
event: 'vpago.payway.check_transaction.error',
|
|
71
|
+
version: 'v2',
|
|
72
|
+
payment_number: transaction_id,
|
|
73
|
+
runtime_ms: runtime_ms,
|
|
74
|
+
error_class: e.class.name,
|
|
75
|
+
error_message: e.message
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
raise
|
|
50
79
|
end
|
|
51
80
|
|
|
52
81
|
def payout_total
|
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.1.
|
|
4
|
+
version: 2.1.9.pre.add.pre.payment.pre.processor.pre.job.pre.logging
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- You
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-02-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -188,6 +188,7 @@ files:
|
|
|
188
188
|
- app/jobs/vpago/payment_capturer_job.rb
|
|
189
189
|
- app/jobs/vpago/payment_processor_job.rb
|
|
190
190
|
- app/jobs/vpago/payment_voider_job.rb
|
|
191
|
+
- app/lib/vpago/timing_helper.rb
|
|
191
192
|
- app/models/.gitkeep
|
|
192
193
|
- app/models/concerns/vpago/payoutable.rb
|
|
193
194
|
- app/models/spree/gateway/acleda.rb
|
|
@@ -198,6 +199,7 @@ files:
|
|
|
198
199
|
- app/models/spree/gateway/vattanac.rb
|
|
199
200
|
- app/models/spree/gateway/vattanac_mini_app.rb
|
|
200
201
|
- app/models/spree/gateway/wing_sdk.rb
|
|
202
|
+
- app/models/spree/payment_method/cash_on.rb
|
|
201
203
|
- app/models/spree/payout.rb
|
|
202
204
|
- app/models/spree/payout_profile.rb
|
|
203
205
|
- app/models/spree/payout_profile_product.rb
|
|
@@ -438,9 +440,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
438
440
|
version: 3.2.0
|
|
439
441
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
440
442
|
requirements:
|
|
441
|
-
- - "
|
|
443
|
+
- - ">"
|
|
442
444
|
- !ruby/object:Gem::Version
|
|
443
|
-
version:
|
|
445
|
+
version: 1.3.1
|
|
444
446
|
requirements:
|
|
445
447
|
- none
|
|
446
448
|
rubygems_version: 3.4.1
|