spree_vpago 2.0.4.pre.beta1 → 2.0.5.pre.beta

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f8ef668be755bd4ef8b3f8efd1685a637fd220b7af387117968333fdf45062c
4
- data.tar.gz: dad512cdc64f169c9daf682fe95c9bd01a9ed1af8e771afb44dec42aa166bbb6
3
+ metadata.gz: 693e45fc6915c023a690b5aa8c3e44cf18e21bcb5c6cc7fd8d520ee964db418a
4
+ data.tar.gz: 602e1ac04e520e6b11452125ae7a88801a8545845df3d5417cb46008ec04bf0a
5
5
  SHA512:
6
- metadata.gz: b9ca740cab5e96deff6ff074c74bcdb40fc9e2afb4228411e68f2b6190143206c9034b21cef23ad7cbe69a994a64103cb1d1d43d529b015c94e15cf6bb4dd94c
7
- data.tar.gz: ff2743d04cfae7ba13ebe54a026ebdf706842f8df82709fcdd95fc930412f00a05945f08beaa2dc32ecbd37a8edcacc371f386f847afa5842078001f31059c6d
6
+ metadata.gz: ae4e9828ecb2d4cdc9d7abb038b5304ea5f7871a33fba13af4907e87b5351f9c15630137d7c4ae76796a2d469b55003806098f9fb5e8a4a37d83ade2d3e118d9
7
+ data.tar.gz: ff5ea0f427d105324e5d9726c0b7dc44ac84acac1ca8659aeb7f119c60244f577cd0a33e57b1057c0d48ca2f59344894eee7612c71f88b10fc4aa496e34632c7
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- spree_vpago (2.0.4.pre.beta1)
4
+ spree_vpago (2.0.5.pre.beta)
5
5
  faraday
6
6
  google-cloud-firestore
7
7
  spree_api (>= 4.5)
@@ -18,6 +18,7 @@ module Vpago
18
18
  cheque
19
19
  payway_cards
20
20
  wingpay
21
+ vattanac_mini_app
21
22
  ]
22
23
  end
23
24
 
@@ -0,0 +1,75 @@
1
+ module Spree
2
+ class Gateway::VattanacMiniApp < PaymentMethod
3
+
4
+ def method_type
5
+ 'vattanac_mini_app'
6
+ end
7
+
8
+ def payment_source_class
9
+ Spree::VpagoPaymentSource
10
+ end
11
+
12
+ # force to purchase instead of authorize
13
+ def auto_capture?
14
+ true
15
+ end
16
+
17
+
18
+ # override
19
+ # purchase is used when pre auth disabled
20
+ def purchase(_amount, _source, gateway_options = {})
21
+ _, payment_number = gateway_options[:order_id].split('-')
22
+ payment = Spree::Payment.find_by(number: payment_number)
23
+
24
+ params = {}
25
+
26
+ params[:payment_response] = payment.transaction_response
27
+
28
+
29
+ if payment.transaction_response["status"] == 'SUCCESS'
30
+ ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Purchased', params)
31
+ else
32
+ ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Purchasing Failed', params)
33
+ end
34
+
35
+ end
36
+
37
+
38
+ # override
39
+ def void(_response_code, gateway_options)
40
+ _, payment_number = gateway_options[:order_id].split('-')
41
+ payment = Spree::Payment.find_by(number: payment_number)
42
+
43
+ if payment.vattanac_mini_app_payment?
44
+ params = {}
45
+ success, params[:refund_response] = vattanac_mini_app_refund(payment)
46
+
47
+ if success
48
+ ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: successfully canceled.', params)
49
+ else
50
+ ActiveMerchant::Billing::Response.new(false, 'Payway Gateway: Failed to canceleed', params)
51
+ end
52
+ else
53
+ ActiveMerchant::Billing::Response.new(true, 'Payway Gateway: Payment has been voided.')
54
+ end
55
+ end
56
+
57
+
58
+ def vattanac_mini_app_refund(payment)
59
+
60
+ refund_issuer = Vpago::VattanacMiniApp::RefundIssuer.new(payment, {})
61
+ refund_issuer.call
62
+
63
+ [refund_issuer.success?, refund_issuer.response]
64
+
65
+ end
66
+
67
+ def cancel(_response_code)
68
+ # we can use this to send request to payment gateway api to cancel the payment ( void )
69
+ # currently Payway does not support to cancel the gateway
70
+
71
+ # in our case don't do anything
72
+ ActiveMerchant::Billing::Response.new(true, 'Vattanc order has been cancelled.')
73
+ end
74
+ end
75
+ end
@@ -55,6 +55,11 @@ module Vpago
55
55
  def pre_auth_cancelled?
56
56
  pre_auth_status == 'CANCELLED'
57
57
  end
58
+
59
+ def vattanac_mini_app_payment?
60
+ payment_method.type_vattanac_mini_app?
61
+ end
62
+
58
63
  end
59
64
  end
60
65
 
@@ -5,6 +5,7 @@ module Vpago
5
5
  TYPE_WINGSDK = 'Spree::Gateway::WingSdk'.freeze
6
6
  TYPE_ACLEDA = 'Spree::Gateway::Acleda'.freeze
7
7
  TYPE_ACLEDA_MOBILE = 'Spree::Gateway::AcledaMobile'.freeze
8
+ TYPE_VATTANAC_MINI_APP = 'Spree::Gateway::VattanacMiniApp'.freeze
8
9
 
9
10
  def self.prepended(base)
10
11
  base.preference :icon_name, :string, default: 'cheque'
@@ -16,7 +17,8 @@ module Vpago
16
17
  Spree::PaymentMethod::TYPE_PAYWAY,
17
18
  Spree::PaymentMethod::TYPE_WINGSDK,
18
19
  Spree::PaymentMethod::TYPE_ACLEDA,
19
- Spree::PaymentMethod::TYPE_ACLEDA_MOBILE
20
+ Spree::PaymentMethod::TYPE_ACLEDA_MOBILE,
21
+ Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
20
22
  ]
21
23
  end
22
24
  end
@@ -85,6 +87,10 @@ module Vpago
85
87
  def type_wingsdk?
86
88
  type == Spree::PaymentMethod::TYPE_WINGSDK
87
89
  end
90
+
91
+ def type_vattanac_mini_app?
92
+ type == Spree::PaymentMethod::TYPE_VATTANAC_MINI_APP
93
+ end
88
94
  end
89
95
  end
90
96
 
@@ -0,0 +1,56 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+
4
+ module Vpago
5
+ class AesEncrypter
6
+ ALGORITHM = 'aes-256-gcm'.freeze
7
+ KEY_LENGTH = 32
8
+ IV_LENGTH = 12
9
+ TAG_LENGTH = 16
10
+
11
+ def self.encrypt(plaintext, base64_key)
12
+ key = Base64.decode64(base64_key)
13
+ validate_key!(key)
14
+
15
+ cipher = OpenSSL::Cipher.new(ALGORITHM)
16
+ cipher.encrypt
17
+ cipher.key = key[0, KEY_LENGTH]
18
+ iv = cipher.random_iv
19
+ cipher.iv = iv
20
+
21
+ ciphertext = cipher.update(plaintext) + cipher.final
22
+ tag = cipher.auth_tag
23
+
24
+ combined = iv + ciphertext + tag
25
+ Base64.strict_encode64(combined)
26
+ end
27
+
28
+ def self.decrypt(encrypted_text, base64_key)
29
+ key = Base64.decode64(base64_key)
30
+ validate_key!(key)
31
+
32
+ combined = Base64.decode64(encrypted_text)
33
+ iv = combined[0, IV_LENGTH]
34
+ tag = combined[-TAG_LENGTH..]
35
+ ciphertext = combined[IV_LENGTH...-TAG_LENGTH]
36
+
37
+ cipher = OpenSSL::Cipher.new(ALGORITHM)
38
+ cipher.decrypt
39
+ cipher.key = key[0, KEY_LENGTH]
40
+ cipher.iv = iv
41
+ cipher.auth_tag = tag
42
+
43
+ cipher.update(ciphertext) + cipher.final
44
+ rescue OpenSSL::Cipher::CipherError => e
45
+ raise "Decryption failed: #{e.message}"
46
+ end
47
+
48
+ def self.validate_key!(key)
49
+ return if key.is_a?(String) && key.bytesize >= KEY_LENGTH
50
+
51
+ raise ArgumentError, "Key must be a string of at least #{KEY_LENGTH} bytes"
52
+ end
53
+ end
54
+ end
55
+
56
+
@@ -7,6 +7,7 @@ module Vpago
7
7
  end
8
8
 
9
9
  def find_and_verify
10
+
10
11
  find_and_verify!
11
12
  rescue StandardError, ActiveRecord::RecordNotFound => e
12
13
  Rails.logger.error("PaymentJwtVerifier#find_and_verify error: #{e.class} - #{e.message}")
@@ -14,14 +15,29 @@ module Vpago
14
15
  end
15
16
 
16
17
  def find_and_verify!
17
- order = Spree::Order.find_by!(number: params_hash[:order_number])
18
- verify_jwt!(order)
19
18
 
20
- Spree::Payment.find_by!(number: params_hash[:payment_number])
19
+ if vattanac_mini_app_payload?
20
+ payload = Vpago::VattanacMiniAppDataHandler.new.decrypt_data(@params_hash[:data])
21
+ payment = Spree::Payment.find_by!(number: payload['paymentId'])
22
+ payment.update(transaction_response: payload)
23
+ payment
24
+ else
25
+ order = Spree::Order.find_by!(number: params_hash[:order_number])
26
+ verify_jwt!(order)
27
+
28
+ Spree::Payment.find_by!(number: params_hash[:payment_number])
29
+ end
21
30
  end
22
31
 
23
32
  def verify_jwt!(order)
24
33
  JWT.decode(params_hash[:order_jwt_token], order.token, 'HS256')
25
34
  end
35
+
36
+ def vattanac_mini_app_payload?
37
+ params_hash[:data].present?
38
+ end
39
+
26
40
  end
27
41
  end
42
+
43
+
@@ -16,7 +16,7 @@ module Vpago
16
16
  # 2. Pre-auth is enabled, ensuring funds can be released to user if processing fails.
17
17
  # PaymentProcessor is usually called after payment is made, so canceling pre-auth typically works.
18
18
  def can_cancel_pre_auth?
19
- @payment.pending? || @payment.payment_method.enable_pre_auth?
19
+ @payment.pending? || @payment.payment_method.enable_pre_auth? || @payment.vattanac_mini_app_payment?
20
20
  end
21
21
 
22
22
  def extract_completer_failure_reason_code(error)
@@ -0,0 +1,27 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+
4
+ module Vpago
5
+ class RsaHandler
6
+ def initialize(private_key: nil, public_key: nil)
7
+ @private_key = private_key
8
+ @public_key = public_key
9
+ end
10
+
11
+ def sign(data)
12
+ raise 'Private key is required to sign data' unless @private_key
13
+
14
+ private_key_object = OpenSSL::PKey::RSA.new(@private_key)
15
+ signature = private_key_object.sign(OpenSSL::Digest.new('SHA256'), data)
16
+ "#{data}.#{Base64.strict_encode64(signature)}"
17
+ end
18
+
19
+ def verify(data, signature)
20
+ raise 'Public key is required to verify signature' unless @public_key
21
+
22
+ public_key_object = OpenSSL::PKey::RSA.new(@public_key)
23
+ signature_bytes = Base64.decode64(signature)
24
+ public_key_object.verify(OpenSSL::Digest.new('SHA256'), signature_bytes, data)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ module Vpago
2
+ class VattanacMiniAppDataHandler
3
+ def decrypt_data(data)
4
+ encrypted_data, signature = data.to_s.split('.', 2)
5
+
6
+ return nil unless Vpago::RsaHandler.new(public_key: vattanac_public_key).verify(encrypted_data, signature)
7
+
8
+ decrypted = Vpago::AesEncrypter.decrypt(encrypted_data, aes_key)
9
+ JSON.parse(decrypted) rescue nil
10
+
11
+ end
12
+
13
+ def encrypted_data(payload)
14
+ json_payload = payload.to_json
15
+ encrypted_data = Vpago::AesEncrypter.encrypt(json_payload, aes_key)
16
+ rsa_service = Vpago::RsaHandler.new(private_key: bookmeplus_private_key)
17
+ signed_data = rsa_service.sign(encrypted_data)
18
+ signed_data
19
+ end
20
+
21
+ def vattanac_public_key
22
+ ENV['VATTANAC_PUBLIC_KEY'].presence || Rails.application.credentials.vattanac.public_key
23
+ end
24
+
25
+ def bookmeplus_private_key
26
+ ENV['BOOKMEPLUS_PRIVATE_KEY'].presence || Rails.application.credentials.bookmeplus.private_key
27
+ end
28
+
29
+ def aes_key
30
+ ENV['VATTANAC_AES_SECRET_KEY'].presence || Rails.application.credentials.vattanac.aes_secret_key
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,6 @@
1
+ <%= render 'spree/admin/payments/source_views/vpago_payment_tmpl',
2
+ payment: payment,
3
+ check_status_url: '',
4
+ heal_payment_url: '',
5
+ manual_update_payment_url: ''
6
+ %>
@@ -0,0 +1,89 @@
1
+ <% @checkout = ::Vpago::VattanacMiniApp::Checkout.new(@payment) %>
2
+ <% @payment.user_informer.payment_is_processing(processing: true) %>
3
+
4
+ <p id="unsupported-message"
5
+ style="margin-top: 10px;
6
+ font-weight: bold;
7
+ color: red;
8
+ display: none;">
9
+ </p>
10
+
11
+ <h1 id="status">THIS IS CURRENT STATE</h1>
12
+ <p id="reason_code"></p>
13
+ <p id="processing"></p>
14
+ <p id="reason_message"></p>
15
+
16
+ <script>
17
+
18
+ function detectMobileOS() {
19
+ const ua = navigator.userAgent || navigator.vendor || window.opera;
20
+ if (/iPad|iPhone|iPod/.test(ua) && !window.MSStream) return 'iOS';
21
+ if (/Android/i.test(ua)) return 'Android';
22
+ return 'unknown';
23
+ }
24
+
25
+ document.addEventListener('DOMContentLoaded', () => {
26
+ const os = detectMobileOS();
27
+ const payload = {
28
+ data: "<%= j @checkout.signed_payload %>",
29
+ paymentId: "<%= @checkout.payment_id %>"
30
+ };
31
+
32
+ if (os === 'iOS' && window.webkit?.messageHandlers?.startPayment) {
33
+ window.webkit.messageHandlers.startPayment.postMessage(JSON.stringify(payload));
34
+ } else if (os === 'Android' && window.AndroidInterface?.startPayment) {
35
+ window.AndroidInterface.startPayment(JSON.stringify(payload));
36
+ } else {
37
+ const unsupported = document.getElementById('unsupported-message');
38
+ unsupported.style.display = 'block';
39
+ unsupported.innerText = 'Unsupported OS';
40
+ }
41
+
42
+ const firebaseConfigs = <%= Rails.application.credentials.firebase_web_config.to_json.html_safe %>;
43
+
44
+ window.listenToProcessingState({
45
+ firebaseConfigs: firebaseConfigs,
46
+ documentReferencePath: "<%= @payment.user_informer.document_reference_path %>",
47
+ onPaymentIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
48
+ document.getElementById("status").innerText = "Payment is processing";
49
+ document.getElementById("reason_code").innerText = reasonCode;
50
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
51
+ document.getElementById("reason_message").innerText = reasonMessage;
52
+ },
53
+ onOrderIsProcessing: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
54
+ document.getElementById("status").innerText = "Order is processing";
55
+ document.getElementById("reason_code").innerText = reasonCode;
56
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
57
+ document.getElementById("reason_message").innerText = reasonMessage;
58
+ },
59
+ onOrderIsCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
60
+ document.getElementById("status").innerText = "Order is completed";
61
+ document.getElementById("reason_code").innerText = reasonCode;
62
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
63
+ document.getElementById("reason_message").innerText = reasonMessage;
64
+ },
65
+ onOrderProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
66
+ document.getElementById("status").innerText = "Order process failed";
67
+ document.getElementById("reason_code").innerText = reasonCode;
68
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
69
+ document.getElementById("reason_message").innerText = reasonMessage;
70
+ },
71
+ onPaymentIsRefunded: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
72
+ document.getElementById("status").innerText = "Payment is refunded";
73
+ document.getElementById("reason_code").innerText = reasonCode;
74
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
75
+ document.getElementById("reason_message").innerText = reasonMessage
76
+ },
77
+ onPaymentProcessFailed: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
78
+ document.getElementById("status").innerText = "Payment process failed";
79
+ document.getElementById("reason_code").innerText = reasonCode;
80
+ document.getElementById("processing").innerText = processing ? "Processing..." : "No more process.";
81
+ document.getElementById("reason_message").innerText = reasonMessage;
82
+ },
83
+ onCompleted: function (orderState, paymentState, processing, reasonCode, reasonMessage) {
84
+ let successPath = "<%= @payment.success_url %>";
85
+ window.location.href = successPath;
86
+ },
87
+ });
88
+ });
89
+ </script>
@@ -21,7 +21,8 @@ module SpreeVpago
21
21
  Spree::Gateway::PaywayV2,
22
22
  Spree::Gateway::WingSdk,
23
23
  Spree::Gateway::Acleda,
24
- Spree::Gateway::AcledaMobile
24
+ Spree::Gateway::AcledaMobile,
25
+ Spree::Gateway::VattanacMiniApp
25
26
  )
26
27
  end
27
28
 
@@ -1,7 +1,7 @@
1
1
  module SpreeVpago
2
2
  module_function
3
3
 
4
- VERSION = '2.0.4-beta1'.freeze
4
+ VERSION = '2.0.5-beta'.freeze
5
5
 
6
6
  def version
7
7
  Gem::Version.new VERSION
@@ -0,0 +1,52 @@
1
+ module Vpago
2
+ module VattanacMiniApp
3
+ class Base
4
+
5
+ def initialize(payment, options = {})
6
+ @options = options
7
+ @payment = payment
8
+ end
9
+
10
+ def payload
11
+ {
12
+ paymentId: payment_id,
13
+ amount: amount,
14
+ currency: currency || 'USD',
15
+ expiredIn: expired_at
16
+ }
17
+ end
18
+
19
+ def encrypt_data(payload)
20
+ SpreeCmCommissioner::AesEncryptionService.encrypt(payload.to_json, aes_key)
21
+ end
22
+
23
+ def amount
24
+ @payment.amount
25
+ end
26
+
27
+ def payment_id
28
+ @payment.number
29
+ end
30
+
31
+ def currency
32
+ 'USD'
33
+ end
34
+
35
+ def transaction_id
36
+ @payment.number
37
+ end
38
+
39
+ def expired_at
40
+ (Time.now + 30.minutes).to_i * 1000
41
+ end
42
+
43
+ def partner_code
44
+ ENV['VATTANAC_PARTNER_CODE'].presence
45
+ end
46
+
47
+ def refund_url
48
+ ENV['VATTANAC_REFUND_URL'].presence
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ module Vpago
2
+ module VattanacMiniApp
3
+ class Checkout < Base
4
+ def signed_payload
5
+ Vpago::VattanacMiniAppDataHandler.new.encrypted_data(payload)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,54 @@
1
+ module Vpago
2
+ module VattanacMiniApp
3
+ class RefundIssuer < Base
4
+ attr_reader :response
5
+
6
+ def call
7
+ raw_response = send_refund_request
8
+ @response = handle_response(raw_response)
9
+ end
10
+
11
+ def success?
12
+ @success
13
+ end
14
+
15
+ def send_refund_request
16
+ Faraday.post(refund_url) do |req|
17
+ req.headers['Content-Type'] = 'application/json'
18
+ req.headers['Partner-Code'] = partner_code
19
+ req.body = {
20
+ data: Vpago::VattanacMiniAppDataHandler.new.encrypted_data(refund_payload)
21
+ }.to_json
22
+ end
23
+ end
24
+
25
+ def handle_response(response)
26
+ body = parse_json(response.body)
27
+
28
+ if body['status'] == 'SUCCESS'
29
+ json = Vpago::VattanacMiniAppDataHandler.new.decrypt_data(body['data'])
30
+ @success = true
31
+ json
32
+ else
33
+ @success = false
34
+ body
35
+ end
36
+ end
37
+
38
+ def refund_payload
39
+ {
40
+ transactionId: @payment.transaction_response["transactionId"],
41
+ paymentId: @payment.transaction_response["paymentId"],
42
+ amount: @payment.transaction_response["amount"],
43
+ currency: 'USD'
44
+ }
45
+ end
46
+
47
+ def parse_json(raw)
48
+ JSON.parse(raw)
49
+ rescue JSON::ParserError => e
50
+ raise StandardError, "Invalid JSON: #{e.message}"
51
+ end
52
+ end
53
+ end
54
+ end
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.0.4.pre.beta1
4
+ version: 2.0.5.pre.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-05 00:00:00.000000000 Z
11
+ date: 2025-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -179,6 +179,7 @@ files:
179
179
  - app/models/spree/gateway/acleda_mobile.rb
180
180
  - app/models/spree/gateway/payway.rb
181
181
  - app/models/spree/gateway/payway_v2.rb
182
+ - app/models/spree/gateway/vattanac_mini_app.rb
182
183
  - app/models/spree/gateway/wing_sdk.rb
183
184
  - app/models/spree/payout.rb
184
185
  - app/models/spree/payout_profile.rb
@@ -231,6 +232,7 @@ files:
231
232
  - app/serializers/spree/v2/storefront/payment_serializer_decorator.rb
232
233
  - app/serializers/spree/v2/storefront/vpago_payment_source_serializer.rb
233
234
  - app/services/.gitkeep
235
+ - app/services/vpago/aes_encrypter.rb
234
236
  - app/services/vpago/payment_finder.rb
235
237
  - app/services/vpago/payment_processable.rb
236
238
  - app/services/vpago/payment_processor.rb
@@ -243,7 +245,9 @@ files:
243
245
  - app/services/vpago/payout_profiles/payway/payout_profile_request_params_builder.rb
244
246
  - app/services/vpago/payout_profiles/payway/payout_profile_request_updater.rb
245
247
  - app/services/vpago/payway_return_options_builder.rb
248
+ - app/services/vpago/rsa_handler.rb
246
249
  - app/services/vpago/user_informers/firebase.rb
250
+ - app/services/vpago/vattanac_mini_app_data_handler.rb
247
251
  - app/views/.gitkeep
248
252
  - app/views/layouts/acleda.html.erb
249
253
  - app/views/layouts/payway.html.erb
@@ -258,6 +262,7 @@ files:
258
262
  - app/views/spree/admin/payments/source_views/_acleda_mobile.html.erb
259
263
  - app/views/spree/admin/payments/source_views/_payment_payway.html.erb
260
264
  - app/views/spree/admin/payments/source_views/_payway_v2.html.erb
265
+ - app/views/spree/admin/payments/source_views/_vattanac_mini_app.html.erb
261
266
  - app/views/spree/admin/payments/source_views/_vpago_payment_tmpl.html.erb
262
267
  - app/views/spree/admin/payments/source_views/_wingsdk.html.erb
263
268
  - app/views/spree/admin/payout_profile_products/_form.html.erb
@@ -304,6 +309,7 @@ files:
304
309
  - app/views/spree/payway_v2_card_popups/show.html.erb
305
310
  - app/views/spree/vpago_payments/checkout.html.erb
306
311
  - app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb
312
+ - app/views/spree/vpago_payments/forms/spree/gateway/_vattanac_mini_app.html.erb
307
313
  - app/views/spree/vpago_payments/processing.html.erb
308
314
  - app/views/spree/vpago_payments/success.html.erb
309
315
  - app/views/spree/wing_redirects/show.html.erb
@@ -371,6 +377,9 @@ files:
371
377
  - lib/vpago/payway_v2/pre_auth_canceler.rb
372
378
  - lib/vpago/payway_v2/pre_auth_completer.rb
373
379
  - lib/vpago/payway_v2/transaction_status.rb
380
+ - lib/vpago/vattanac_mini_app/base.rb
381
+ - lib/vpago/vattanac_mini_app/checkout.rb
382
+ - lib/vpago/vattanac_mini_app/refund_issuer.rb
374
383
  - lib/vpago/wing_sdk/base.rb
375
384
  - lib/vpago/wing_sdk/checkout.rb
376
385
  - lib/vpago/wing_sdk/payment_request_updater.rb