spree_vpago 0.1.0.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 +7 -0
- data/.env.example +3 -0
- data/.github/workflows/test_and_publish_gem.yml +96 -0
- data/.gitignore +24 -0
- data/.rspec +3 -0
- data/.rubocop.yml +56 -0
- data/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/.travis.yml +45 -0
- data/Appraisals +20 -0
- data/Gemfile +27 -0
- data/Gemfile.lock +656 -0
- data/LICENSE +26 -0
- data/README.md +151 -0
- data/Rakefile +21 -0
- data/app/.gitkeep +0 -0
- data/app/assets/config/spree_vpago_manifest.js +3 -0
- data/app/assets/images/backend-process.svg +3 -0
- data/app/assets/images/vpago/payway/abapay.png +0 -0
- data/app/assets/images/vpago/payway/cards.png +0 -0
- data/app/assets/javascripts/vpago/vpago_payments/request_process_payment.js +44 -0
- data/app/assets/javascripts/vpago/vpago_payments/user_informers/firebase.js +15802 -0
- data/app/controllers/.gitkeep +0 -0
- data/app/controllers/spree/acleda_redirects_controller.rb +22 -0
- data/app/controllers/spree/admin/payment_methods_controller_decorator.rb +65 -0
- data/app/controllers/spree/admin/payment_payway_base_controller.rb +25 -0
- data/app/controllers/spree/admin/payment_payway_checkers_controller.rb +34 -0
- data/app/controllers/spree/admin/payment_payway_markers_controller.rb +44 -0
- data/app/controllers/spree/admin/payment_payway_queriers_controller.rb +39 -0
- data/app/controllers/spree/admin/payment_wing_sdk_base_controller.rb +21 -0
- data/app/controllers/spree/admin/payment_wing_sdk_checkers_controller.rb +26 -0
- data/app/controllers/spree/admin/payment_wing_sdk_markers_controller.rb +36 -0
- data/app/controllers/spree/admin/payment_wing_sdk_queriers_controller.rb +20 -0
- data/app/controllers/spree/admin/payments_controller_decorator.rb +19 -0
- data/app/controllers/spree/admin/payout_profile_products_controller.rb +21 -0
- data/app/controllers/spree/admin/payout_profile_shipping_methods_controller.rb +21 -0
- data/app/controllers/spree/admin/payout_profiles_controller.rb +91 -0
- data/app/controllers/spree/admin/payouts_controller.rb +16 -0
- data/app/controllers/spree/api/v2/storefront/checkout_controller_decorator.rb +84 -0
- data/app/controllers/spree/payway_card_popups_controller.rb +20 -0
- data/app/controllers/spree/payway_results_controller.rb +11 -0
- data/app/controllers/spree/payway_v2_card_popups_controller.rb +20 -0
- data/app/controllers/spree/vpago_payments_controller.rb +71 -0
- data/app/controllers/spree/webhook/acleda_mobiles_controller.rb +88 -0
- data/app/controllers/spree/webhook/acledas_controller.rb +80 -0
- data/app/controllers/spree/webhook/base_controller.rb +6 -0
- data/app/controllers/spree/webhook/payways_controller.rb +77 -0
- data/app/controllers/spree/webhook/wings_controller.rb +63 -0
- data/app/controllers/spree/wing/base_controller.rb +29 -0
- data/app/controllers/spree/wing/transactions_controller.rb +27 -0
- data/app/controllers/spree/wing_redirects_controller.rb +20 -0
- data/app/helpers/vpago/admin/base_helper_decorator.rb +40 -0
- data/app/helpers/vpago/vpago_payments_helper.rb +12 -0
- data/app/javascripts/vpago/vpago_payments/user_informers/firebase.js +62 -0
- data/app/jobs/application_unique_job.rb +1 -0
- data/app/jobs/vpago/payment_processor_job.rb +8 -0
- data/app/models/.gitkeep +0 -0
- data/app/models/concerns/vpago/payoutable.rb +11 -0
- data/app/models/spree/gateway/acleda.rb +63 -0
- data/app/models/spree/gateway/acleda_mobile.rb +46 -0
- data/app/models/spree/gateway/payway.rb +66 -0
- data/app/models/spree/gateway/payway_v2.rb +174 -0
- data/app/models/spree/gateway/wing_sdk.rb +51 -0
- data/app/models/spree/payout.rb +23 -0
- data/app/models/spree/payout_profile.rb +107 -0
- data/app/models/spree/payout_profile_product.rb +14 -0
- data/app/models/spree/payout_profile_shipping_method.rb +14 -0
- data/app/models/spree/payout_profiles/payway_v2.rb +40 -0
- data/app/models/spree/vpago_payment_source.rb +21 -0
- data/app/models/vpago/adjustment_decorator.rb +28 -0
- data/app/models/vpago/line_item_decorator.rb +75 -0
- data/app/models/vpago/order_decorator.rb +78 -0
- data/app/models/vpago/payment_decorator.rb +44 -0
- data/app/models/vpago/payment_method_decorator.rb +91 -0
- data/app/models/vpago/payouts_generator.rb +125 -0
- data/app/models/vpago/product_decorator.rb +30 -0
- data/app/models/vpago/promotion_action_decorator.rb +9 -0
- data/app/models/vpago/shipment_decorator.rb +23 -0
- data/app/models/vpago/shipping_method_decorator.rb +33 -0
- data/app/models/vpago/shipping_rate_decorator.rb +25 -0
- data/app/models/vpago/store_decorator.rb +17 -0
- data/app/models/vpago/tax_category_decorator.rb +9 -0
- data/app/models/vpago/variant_decorator.rb +22 -0
- data/app/models/vpago/vendor_decorator.rb +10 -0
- data/app/overrides/spree/admin/adjustments/_adjustment/handle_by_table_body.html.erb.deface +11 -0
- data/app/overrides/spree/admin/adjustments/_adjustments_table/handle_by_table_header.html.erb.deface +3 -0
- data/app/overrides/spree/admin/adjustments/_form/handle_by_field.html.erb.deface +10 -0
- data/app/overrides/spree/admin/orders/_shipment/edit_method.html.erb.deface +26 -0
- data/app/overrides/spree/admin/orders/_shipment/show_method.html.erb.deface +27 -0
- data/app/overrides/spree/admin/payment_methods/_form/enable_pre_auth_field.html.erb.deface +17 -0
- data/app/overrides/spree/admin/payment_methods/_form/vendor_field.html.erb.deface +6 -0
- data/app/overrides/spree/admin/payment_methods/index/list.html.erb.deface +45 -0
- data/app/overrides/spree/admin/payment_methods/index/payment_methods_tabs.html.erb.deface +9 -0
- data/app/overrides/spree/admin/payment_methods/index/vendor_body.html.erb.deface +5 -0
- data/app/overrides/spree/admin/payment_methods/index/vendor_header.html.erb.deface +5 -0
- data/app/overrides/spree/admin/payments/_list/actions.html.erb.deface +13 -0
- data/app/overrides/spree/admin/promotions/_promotion_action/run_by_field.html.erb.deface +13 -0
- data/app/overrides/spree/admin/shared/_order_tabs/payouts.html.erb.deface +8 -0
- data/app/overrides/spree/admin/shared/_product_tabs/payout_profile_products.html.erb.deface +8 -0
- data/app/overrides/spree/admin/shared/sub_menu/_integrations/payout_profiles.html.erb.deface +3 -0
- data/app/overrides/spree/admin/shipping_methods/_form/handle_by.html.erb.deface +12 -0
- data/app/overrides/spree/admin/shipping_methods/edit/shipping_method_tabs.html.erb.deface +3 -0
- data/app/overrides/spree/admin/tax_categories/_form/collect_by_field.html.erb.deface +10 -0
- data/app/overrides/spree/admin/tax_categories/index/collect_by_table_body.html.erb.deface +4 -0
- data/app/overrides/spree/admin/tax_categories/index/collect_by_table_header.html.erb.deface +4 -0
- data/app/serializers/spree/api/v2/platform/vpago_payment_source_serializer.rb +11 -0
- data/app/serializers/spree/v2/storefront/payment_method_serializer_decorator.rb +23 -0
- data/app/serializers/spree/v2/storefront/payment_redirect_serializer.rb +13 -0
- data/app/serializers/spree/v2/storefront/payment_serializer_decorator.rb +13 -0
- data/app/serializers/spree/v2/storefront/vpago_payment_source_serializer.rb +9 -0
- data/app/services/.gitkeep +0 -0
- data/app/services/vpago/payment_finder.rb +27 -0
- data/app/services/vpago/payment_processor.rb +72 -0
- data/app/services/vpago/payment_redirect_handler.rb +194 -0
- data/app/services/vpago/payment_url_constructor.rb +32 -0
- data/app/services/vpago/payments/find_or_create.rb +51 -0
- data/app/services/vpago/payout_profiles/payway/base_payout_profile_request.rb +38 -0
- data/app/services/vpago/payout_profiles/payway/open_ssl_encrypter.rb +31 -0
- data/app/services/vpago/payout_profiles/payway/payout_profile_request_creator.rb +50 -0
- data/app/services/vpago/payout_profiles/payway/payout_profile_request_params_builder.rb +58 -0
- data/app/services/vpago/payout_profiles/payway/payout_profile_request_updater.rb +28 -0
- data/app/services/vpago/payway_return_options_builder.rb +39 -0
- data/app/services/vpago/user_informers/firebase.rb +52 -0
- data/app/views/.gitkeep +0 -0
- data/app/views/layouts/acleda.html.erb +18 -0
- data/app/views/layouts/payway.html.erb +24 -0
- data/app/views/layouts/payway_v2.html.erb +18 -0
- data/app/views/layouts/vpago_payments.html.erb +18 -0
- data/app/views/layouts/wing.html.erb +18 -0
- data/app/views/spree/_payment_icon.html.erb +25 -0
- data/app/views/spree/acleda_redirects/show.html.erb +3 -0
- data/app/views/spree/admin/payments/source_forms/_payment_payway.html.erb +4 -0
- data/app/views/spree/admin/payments/source_forms/_payway_v2.html.erb +7 -0
- data/app/views/spree/admin/payments/source_views/_acleda.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_acleda_mobile.html.erb +1 -0
- data/app/views/spree/admin/payments/source_views/_payment_payway.html.erb +98 -0
- data/app/views/spree/admin/payments/source_views/_payway_v2.html.erb +5 -0
- data/app/views/spree/admin/payments/source_views/_vpago_payment_tmpl.html.erb +113 -0
- data/app/views/spree/admin/payments/source_views/_wingsdk.html.erb +5 -0
- data/app/views/spree/admin/payout_profile_products/_form.html.erb +28 -0
- data/app/views/spree/admin/payout_profile_products/edit.html.erb +18 -0
- data/app/views/spree/admin/payout_profile_products/index.html.erb +58 -0
- data/app/views/spree/admin/payout_profile_products/new.html.erb +22 -0
- data/app/views/spree/admin/payout_profile_shipping_methods/_form.html.erb +28 -0
- data/app/views/spree/admin/payout_profile_shipping_methods/edit.html.erb +22 -0
- data/app/views/spree/admin/payout_profile_shipping_methods/index.html.erb +6 -0
- data/app/views/spree/admin/payout_profile_shipping_methods/new.html.erb +27 -0
- data/app/views/spree/admin/payout_profiles/_filter.html.erb +19 -0
- data/app/views/spree/admin/payout_profiles/_form.html.erb +72 -0
- data/app/views/spree/admin/payout_profiles/edit.html.erb +33 -0
- data/app/views/spree/admin/payout_profiles/index.html.erb +63 -0
- data/app/views/spree/admin/payout_profiles/new.html.erb +13 -0
- data/app/views/spree/admin/payouts/_line_item_info_with_popover.html.erb +43 -0
- data/app/views/spree/admin/payouts/index.html.erb +46 -0
- data/app/views/spree/admin/shared/_payment_methods_tabs.html.erb +15 -0
- data/app/views/spree/admin/shared/_shipping_method_tabs.html.erb +19 -0
- data/app/views/spree/admin/shared/payout_profile/_info_card.html.erb +24 -0
- data/app/views/spree/admin/shared/payout_profile/_status.html.erb +11 -0
- data/app/views/spree/checkout/payment/_acleda.html.erb +1 -0
- data/app/views/spree/checkout/payment/_acleda_checkout_form.html.erb +14 -0
- data/app/views/spree/checkout/payment/_acleda_mobile.html.erb +0 -0
- data/app/views/spree/checkout/payment/_payment_payway.html.erb +21 -0
- data/app/views/spree/checkout/payment/_payway_loader.html.erb +2 -0
- data/app/views/spree/checkout/payment/_payway_root.html.erb +9 -0
- data/app/views/spree/checkout/payment/_payway_script.html.erb +77 -0
- data/app/views/spree/checkout/payment/_payway_v2.html.erb +1 -0
- data/app/views/spree/checkout/payment/_payway_v2_loader.html.erb +2 -0
- data/app/views/spree/checkout/payment/_payway_v2_root.html.erb +9 -0
- data/app/views/spree/checkout/payment/_payway_v2_script.html.erb +79 -0
- data/app/views/spree/checkout/payment/_wing_checkout_form.html.erb +18 -0
- data/app/views/spree/checkout/payment/_wingsdk.html.erb +1 -0
- data/app/views/spree/checkout/payment/acleda_form.html.erb +3 -0
- data/app/views/spree/checkout/payment/payway_form.html.erb +10 -0
- data/app/views/spree/checkout/payment/payway_v2_form.html.erb +10 -0
- data/app/views/spree/checkout/payment/wingsdk_form.html.erb +3 -0
- data/app/views/spree/payway_card_popups/_form.html.erb +10 -0
- data/app/views/spree/payway_card_popups/show.html.erb +5 -0
- data/app/views/spree/payway_results/failed.html.erb +1 -0
- data/app/views/spree/payway_results/success.html.erb +1 -0
- data/app/views/spree/payway_v2_card_popups/_form.html.erb +15 -0
- data/app/views/spree/payway_v2_card_popups/show.html.erb +3 -0
- data/app/views/spree/vpago_payments/checkout.html.erb +3 -0
- data/app/views/spree/vpago_payments/forms/spree/gateway/_payway_v2.html.erb +13 -0
- data/app/views/spree/vpago_payments/processing.html.erb +49 -0
- data/app/views/spree/vpago_payments/success.html.erb +3 -0
- data/app/views/spree/wing_redirects/show.html.erb +3 -0
- data/bin/rails +8 -0
- data/build.js +9 -0
- data/config/initializers/assets.rb +1 -0
- data/config/initializers/spree_permitted_attributes.rb +5 -0
- data/config/locales/en.yml +28 -0
- data/config/locales/km.yml +24 -0
- data/config/routes.rb +92 -0
- data/db/migrate/20210128040625_create_spree_vpago_payment_sources.rb +14 -0
- data/db/migrate/20210430052432_add_fields_to_payment_sources.rb +7 -0
- data/db/migrate/20210824044737_add_preference_to_spree_vpago_payment_source.rb +5 -0
- data/db/migrate/20240506095140_create_spree_payout_profiles.rb +22 -0
- data/db/migrate/20240506095148_create_spree_payout_profile_products.rb +10 -0
- data/db/migrate/20240523070757_add_optional_spere_payout_profile_products.rb +5 -0
- data/db/migrate/20240715091228_create_spree_payouts.rb +25 -0
- data/db/migrate/20240718195510_create_spree_payout_profile_shipping_methods.rb +15 -0
- data/db/migrate/20240718201453_add_handle_by_to_spree_adjustments.rb +5 -0
- data/db/migrate/20240718201509_add_run_by_to_spree_promotion_actions.rb +5 -0
- data/db/migrate/20240718201523_add_collect_by_to_spree_tax_categories.rb +5 -0
- data/db/migrate/20240718201538_add_handle_by_to_spree_shipping_method.rb +5 -0
- data/db/migrate/20240718201554_add_handle_by_to_spree_shipping_rates.rb +5 -0
- data/db/migrate/20240808102853_add_vendor_reference_to_spree_payment_methods.rb +7 -0
- data/db/migrate/20240904030132_add_gateway_status_to_spree_payments.rb +5 -0
- data/db/migrate/20241029071959_add_pre_auth_response_to_spree_payment.rb +5 -0
- data/db/migrate/20241202104014_add_enable_pre_auth_to_spree_payment_method.rb +5 -0
- data/db/migrate/20250121044614_add_transaction_response_to_spree_payments.rb +5 -0
- data/docs/acleda.md +65 -0
- data/gemfiles/spree_3_7.gemfile +9 -0
- data/gemfiles/spree_4_0.gemfile +8 -0
- data/gemfiles/spree_4_1.gemfile +9 -0
- data/gemfiles/spree_master.gemfile +8 -0
- data/lib/generators/spree_vpago/install/install_generator.rb +26 -0
- data/lib/generators/spree_vpago/install/templates/app/assets/images/vpago/payway/acleda_merchant_logo_300x300.png +0 -0
- data/lib/spree_vpago/engine.rb +36 -0
- data/lib/spree_vpago/factories.rb +6 -0
- data/lib/spree_vpago/version.rb +9 -0
- data/lib/spree_vpago.rb +5 -0
- data/lib/vpago/acleda/base.rb +111 -0
- data/lib/vpago/acleda/checkout.rb +105 -0
- data/lib/vpago/acleda/deeplink_checkout.rb +74 -0
- data/lib/vpago/acleda/payment_request_updater.rb +38 -0
- data/lib/vpago/acleda/transaction_status.rb +71 -0
- data/lib/vpago/acleda_mobile/base.rb +28 -0
- data/lib/vpago/acleda_mobile/callback_validator.php +35 -0
- data/lib/vpago/acleda_mobile/callback_validator.rb +38 -0
- data/lib/vpago/acleda_mobile/checkout.rb +78 -0
- data/lib/vpago/acleda_mobile/payment_request_updater.rb +34 -0
- data/lib/vpago/acleda_mobile/payment_retriever.rb +24 -0
- data/lib/vpago/acleda_mobile/transaction_status.rb +35 -0
- data/lib/vpago/payment_amount_calculator.rb +23 -0
- data/lib/vpago/payment_request_updater.rb +19 -0
- data/lib/vpago/payment_status_marker.rb +109 -0
- data/lib/vpago/payway/base.rb +112 -0
- data/lib/vpago/payway/checkout.rb +24 -0
- data/lib/vpago/payway/payment_request_updater.rb +31 -0
- data/lib/vpago/payway/payment_status_marker.rb +84 -0
- data/lib/vpago/payway/transaction_status.rb +74 -0
- data/lib/vpago/payway.rb +13 -0
- data/lib/vpago/payway_v2/base.rb +153 -0
- data/lib/vpago/payway_v2/checkout.rb +35 -0
- data/lib/vpago/payway_v2/payment_request_updater.rb +65 -0
- data/lib/vpago/payway_v2/payouts_params_constructor.rb +47 -0
- data/lib/vpago/payway_v2/pre_auth_canceler.rb +43 -0
- data/lib/vpago/payway_v2/pre_auth_completer.rb +76 -0
- data/lib/vpago/payway_v2/transaction_status.rb +85 -0
- data/lib/vpago/wing_sdk/base.rb +58 -0
- data/lib/vpago/wing_sdk/checkout.rb +20 -0
- data/lib/vpago/wing_sdk/payment_request_updater.rb +46 -0
- data/lib/vpago/wing_sdk/payment_retriever.rb +34 -0
- data/lib/vpago/wing_sdk/transaction_status_checker.rb +64 -0
- data/lib/vpago/wing_sdk/transaction_status_response.rb +33 -0
- data/node_modules/.yarn-integrity +147 -0
- data/package-lock.json +1491 -0
- data/package.json +10 -0
- data/spree_vpago.gemspec +33 -0
- data/yarn.lock +921 -0
- metadata +403 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
module Spree
|
2
|
+
class VpagoPaymentsController < ApplicationController
|
3
|
+
layout 'vpago_payments'
|
4
|
+
helper 'vpago/vpago_payments'
|
5
|
+
|
6
|
+
skip_before_action :verify_authenticity_token, only: [:process_payment]
|
7
|
+
|
8
|
+
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
|
9
|
+
rescue_from CanCan::AccessDenied, with: :access_denied
|
10
|
+
|
11
|
+
# GET
|
12
|
+
def checkout
|
13
|
+
@payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
|
14
|
+
raise ActiveRecord::RecordNotFound unless @payment.present?
|
15
|
+
|
16
|
+
return redirect_to @payment.processing_url, allow_other_host: true unless @payment.checkout?
|
17
|
+
|
18
|
+
@order = @payment.order
|
19
|
+
end
|
20
|
+
|
21
|
+
# GET
|
22
|
+
def processing
|
23
|
+
@payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
|
24
|
+
raise ActiveRecord::RecordNotFound unless @payment.present?
|
25
|
+
|
26
|
+
@order = @payment.order
|
27
|
+
end
|
28
|
+
|
29
|
+
# GET
|
30
|
+
def success
|
31
|
+
@payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
|
32
|
+
raise ActiveRecord::RecordNotFound unless @payment.present?
|
33
|
+
|
34
|
+
@order = @payment.order
|
35
|
+
raise CanCan::AccessDenied unless @order.completed?
|
36
|
+
end
|
37
|
+
|
38
|
+
# POST
|
39
|
+
def process_payment
|
40
|
+
return render json: { status: :ok }, status: :ok if request.method != 'POST'
|
41
|
+
|
42
|
+
@payment = Vpago::PaymentFinder.new(params.permit!.to_h).find_and_verify
|
43
|
+
return render_not_found unless @payment.present?
|
44
|
+
|
45
|
+
unless @payment.order.paid?
|
46
|
+
Vpago::PaymentProcessorJob.perform_later(
|
47
|
+
payment_number: @payment.number
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
render json: { status: :ok }, status: :ok
|
52
|
+
rescue StandardError => e
|
53
|
+
Rails.logger.error("Failed to enqueued payment processor job: #{params} #{e.message}")
|
54
|
+
render json: { status: :internal_server_error, message: 'Failed to enqueue payment processor job' }, status: :internal_server_error
|
55
|
+
end
|
56
|
+
|
57
|
+
def record_not_found
|
58
|
+
respond_to do |format|
|
59
|
+
format.html { render file: Rails.public_path.join('404.html'), status: :not_found, layout: false }
|
60
|
+
format.json { render json: { status: :not_found }, status: :not_found }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def access_denied
|
65
|
+
respond_to do |format|
|
66
|
+
format.html { render file: Rails.public_path.join('422.html'), status: :not_found, layout: false }
|
67
|
+
format.json { render json: { status: :unauthorized }, status: :unauthorized }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Spree
|
2
|
+
module Webhook
|
3
|
+
class AcledaMobilesController < BaseController
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
before_action :find_payment, only: [:return]
|
6
|
+
|
7
|
+
# {
|
8
|
+
# "TransactionId": "16de81d4-b5ef-ef59-16de-81d4b5efef59",
|
9
|
+
# "PaymentTokenId": "REF0361472663", VTENH payment number
|
10
|
+
# "TxnAmount": "30",
|
11
|
+
# "SenderName": "Test User",
|
12
|
+
# "SignedHash": "c5b9be690bde7dc8a0abebb1a45c0850359540a4977aecd4cdf13e15a2edfe79"
|
13
|
+
# }
|
14
|
+
def return
|
15
|
+
request_updater = ::Vpago::AcledaMobile::PaymentRequestUpdater.new(@payment)
|
16
|
+
request_updater.call
|
17
|
+
|
18
|
+
order = @payment.order
|
19
|
+
order = order.reload
|
20
|
+
|
21
|
+
if order.paid? || @payment.pending?
|
22
|
+
render_success
|
23
|
+
else
|
24
|
+
render_failed
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def find_payment
|
31
|
+
options = params.slice(:TransactionId, :PaymentTokenId, :TxnAmount, :SenderName, :SignedHash)
|
32
|
+
|
33
|
+
service = Vpago::AcledaMobile::PaymentRetriever.new(options)
|
34
|
+
service.call
|
35
|
+
|
36
|
+
return render_hashing_error unless service.data_valid?
|
37
|
+
|
38
|
+
@payment = service.payment
|
39
|
+
return render_payment_not_found if @payment.blank?
|
40
|
+
end
|
41
|
+
|
42
|
+
def render_success
|
43
|
+
status_code = 200
|
44
|
+
response_data = acleda_mobile_response_data('Success', status_code)
|
45
|
+
|
46
|
+
acleda_mobile_response(response_data, status_code)
|
47
|
+
end
|
48
|
+
|
49
|
+
def render_failed
|
50
|
+
status_code = 201
|
51
|
+
response_data = acleda_mobile_response_data('Failed', status_code)
|
52
|
+
|
53
|
+
acleda_mobile_response(response_data, status_code)
|
54
|
+
end
|
55
|
+
|
56
|
+
def render_payment_not_found
|
57
|
+
status_code = 203
|
58
|
+
response_data = acleda_mobile_response_data('Payment not found', status_code)
|
59
|
+
|
60
|
+
acleda_mobile_response(response_data, status_code)
|
61
|
+
end
|
62
|
+
|
63
|
+
def render_hashing_error
|
64
|
+
status_code = 403
|
65
|
+
response_data = acleda_mobile_response_data('Invalid SignedHash', status_code)
|
66
|
+
|
67
|
+
acleda_mobile_response(response_data, status_code)
|
68
|
+
end
|
69
|
+
|
70
|
+
def acleda_mobile_response(response_data, status_code)
|
71
|
+
render json: response_data, status: status_code
|
72
|
+
end
|
73
|
+
|
74
|
+
def acleda_mobile_response_data(message, code)
|
75
|
+
{
|
76
|
+
status: {
|
77
|
+
code: code,
|
78
|
+
message: message
|
79
|
+
},
|
80
|
+
data: {
|
81
|
+
TransactionId: params[:TransactionId],
|
82
|
+
PaymentTokenId: params[:PaymentTokenId]
|
83
|
+
}
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Spree
|
2
|
+
module Webhook
|
3
|
+
class AcledasController < BaseController
|
4
|
+
skip_before_action :verify_authenticity_token, only: [:return]
|
5
|
+
|
6
|
+
before_action :find_payment, only: %i[success error return]
|
7
|
+
|
8
|
+
rescue_from ::ActiveRecord::RecordNotFound, with: :record_not_found
|
9
|
+
|
10
|
+
## call back after transaction complete at acleda system
|
11
|
+
## {"amount": "15.0", "_transactionid"=>"PJ9ETZD4", "_paymentresult"=>"SUCCESS", "_paymenttokenid"=>"lVqWKcLHVk6s0rIgk/T8Vdbzsg0=", "_resultCode"=>"0"}
|
12
|
+
def return
|
13
|
+
render_plain = true
|
14
|
+
check_and_redirect(render_plain)
|
15
|
+
end
|
16
|
+
|
17
|
+
## success
|
18
|
+
## {"_arNo"=>"PJ9ETZD4", "_transactionid"=>"PJ9ETZD4", "_paymentresult"=>"SUCCESS", "_paymenttokenid"=>"lVqWKcLHVk6s0rIgk/T8Vdbzsg0=", "_resultCode"=>"0", "controller"=>"spree/webhook/acledas", "action"=>"success"}
|
19
|
+
def success
|
20
|
+
check_and_redirect
|
21
|
+
end
|
22
|
+
|
23
|
+
def error
|
24
|
+
order = @payment.order
|
25
|
+
|
26
|
+
if order.paid?
|
27
|
+
flash[:order_completed] = '1' # required by order_just_completed for purchase tracking
|
28
|
+
end
|
29
|
+
|
30
|
+
pending_or_paid = order.paid? || @payment.pending?
|
31
|
+
if params[:app_checkout].to_s == '1'
|
32
|
+
redirect_to pending_or_paid ? success_payway_results_path : failed_payway_results_path
|
33
|
+
else
|
34
|
+
redirect_to pending_or_paid ? order_path(order) : checkout_state_path(:payment)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def check_and_redirect(render_plain: false)
|
41
|
+
request_updater = ::Vpago::Acleda::PaymentRequestUpdater.new(@payment)
|
42
|
+
request_updater.call
|
43
|
+
|
44
|
+
order = @payment.order
|
45
|
+
order = order.reload
|
46
|
+
|
47
|
+
if render_plain
|
48
|
+
order.paid? || @payment.pending? ? render(plain: :success) : render(plain: :failed, status: 400)
|
49
|
+
else
|
50
|
+
redirect_order(order)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def redirect_order(order)
|
55
|
+
pending_or_paid = order.paid? || @payment.pending?
|
56
|
+
|
57
|
+
if params[:app_checkout].to_s == '1'
|
58
|
+
redirect_to pending_or_paid ? success_payway_results_path : failed_payway_results_path
|
59
|
+
else
|
60
|
+
flash[:order_completed] = '1' if order.paid? # required by order_just_completed for purchase tracking
|
61
|
+
redirect_to pending_or_paid ? order_path(order) : checkout_state_path(:payment)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_payment
|
66
|
+
@payment = nil
|
67
|
+
raise ::ActiveRecord::RecordNotFound if params[:_paymenttokenid].blank?
|
68
|
+
|
69
|
+
payment_source = Spree::VpagoPaymentSource.find_by(transaction_id: params[:_paymenttokenid])
|
70
|
+
raise ::ActiveRecord::RecordNotFound if payment_source.blank?
|
71
|
+
|
72
|
+
@payment = payment_source.payment
|
73
|
+
end
|
74
|
+
|
75
|
+
def record_not_found
|
76
|
+
render(plain: :payment_not_found, status: 404)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Spree
|
2
|
+
module Webhook
|
3
|
+
class PaywaysController < BaseController
|
4
|
+
skip_before_action :verify_authenticity_token, only: %i[return v2_return continue v2_continue]
|
5
|
+
|
6
|
+
# match via: [:get, :post]
|
7
|
+
# {"response"=>"{\"tran_id\":\"PE13LXT1\",\"status\":0"}"}
|
8
|
+
def v2_return
|
9
|
+
handler_service = v2_request_updater_service
|
10
|
+
|
11
|
+
return_callback_handler(handler_service)
|
12
|
+
end
|
13
|
+
|
14
|
+
def return
|
15
|
+
handler_service = request_updater_service
|
16
|
+
|
17
|
+
return_callback_handler(handler_service)
|
18
|
+
end
|
19
|
+
|
20
|
+
# https://vtenh.herokuapp.com/payways/continue?tran_id=P2W2S1LB
|
21
|
+
def v2_continue
|
22
|
+
continue_callback_handler
|
23
|
+
end
|
24
|
+
|
25
|
+
def continue
|
26
|
+
continue_callback_handler
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def v2_request_updater_service
|
32
|
+
::Vpago::PaywayV2::PaymentRequestUpdater
|
33
|
+
end
|
34
|
+
|
35
|
+
def request_updater_service
|
36
|
+
::Vpago::Payway::PaymentRequestUpdater
|
37
|
+
end
|
38
|
+
|
39
|
+
# the callback invoke by PAYWAY in case of success
|
40
|
+
def return_callback_handler(handler_service)
|
41
|
+
# pawway send get request with nothing
|
42
|
+
return render plain: :ok if request.method == 'GET'
|
43
|
+
|
44
|
+
builder = Vpago::PaywayReturnOptionsBuilder.new(params: params)
|
45
|
+
payment = builder.payment
|
46
|
+
|
47
|
+
request_updater = handler_service.new(payment)
|
48
|
+
request_updater.call
|
49
|
+
|
50
|
+
order = payment.order
|
51
|
+
order = order.reload
|
52
|
+
|
53
|
+
if order.paid? || payment.pending?
|
54
|
+
render plain: :success
|
55
|
+
else
|
56
|
+
render plain: :failed, status: 400
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def continue_callback_handler
|
61
|
+
payment = Spree::Payment.find_by number: params[:tran_id]
|
62
|
+
order = payment.order
|
63
|
+
|
64
|
+
if order.paid?
|
65
|
+
flash[:order_completed] = '1' # required by order_just_completed for purchase tracking
|
66
|
+
end
|
67
|
+
|
68
|
+
pending_or_paid = order.paid? || payment.pending?
|
69
|
+
if params[:app_checkout] == 'yes'
|
70
|
+
redirect_to pending_or_paid ? success_payway_results_path : failed_payway_results_path
|
71
|
+
else
|
72
|
+
redirect_to pending_or_paid ? order_path(order) : checkout_state_path(:payment)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Spree
|
2
|
+
module Webhook
|
3
|
+
class WingsController < BaseController
|
4
|
+
skip_before_action :verify_authenticity_token, only: %i[return continue create]
|
5
|
+
|
6
|
+
before_action :retrive_payment, only: [:create]
|
7
|
+
before_action :find_payment, only: %i[return continue]
|
8
|
+
|
9
|
+
def create
|
10
|
+
render_plain = true
|
11
|
+
check_and_redirect(render_plain)
|
12
|
+
end
|
13
|
+
|
14
|
+
## click on button Done: POST { wing_id: payment_number, response: {"remark"=>"PNRE5V5E", "amount"=>" USD 30.00", "total"=>" USD 30.00", "transaction_id"=>"ONL031157", "customer_name"=>"Wing Testing WCX-USD", "biller_name"=>"VTENH"}}
|
15
|
+
## click on button Back: GET { wing_id: payment_number }
|
16
|
+
def return
|
17
|
+
check_and_redirect
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def find_payment
|
23
|
+
@payment = ::Spree::Payment.find_by(number: params[:wing_id])
|
24
|
+
end
|
25
|
+
|
26
|
+
def retrive_payment
|
27
|
+
wing_payment_method = Spree::PaymentMethod.find_by(type: Spree::PaymentMethod::TYPE_WINGSDK)
|
28
|
+
rest_api_key = wing_payment_method.preferences[:rest_api_key]
|
29
|
+
wing_response = params[:contents]
|
30
|
+
|
31
|
+
payment_retriever = ::Vpago::WingSdk::PaymentRetriever.new(rest_api_key, wing_response)
|
32
|
+
payment_retriever.call
|
33
|
+
|
34
|
+
@payment = payment_retriever.payment
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_and_redirect(render_plain: false)
|
38
|
+
request_updater = ::Vpago::WingSdk::PaymentRequestUpdater.new(@payment)
|
39
|
+
request_updater.call
|
40
|
+
|
41
|
+
order = @payment.order
|
42
|
+
order = order.reload
|
43
|
+
|
44
|
+
pending_or_paid = order.paid? || @payment.pending?
|
45
|
+
if render_plain
|
46
|
+
pending_or_paid ? render(plain: :success) : render(plain: :failed, status: 400)
|
47
|
+
else
|
48
|
+
redirect_order(order)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def redirect_order(order)
|
53
|
+
pending_or_paid = order.paid? || @payment.pending?
|
54
|
+
if params[:app_checkout] == 'yes'
|
55
|
+
redirect_to pending_or_paid ? success_payway_results_path : failed_payway_results_path
|
56
|
+
else
|
57
|
+
flash[:order_completed] = '1' if order.paid? # required by order_just_completed for purchase tracking
|
58
|
+
redirect_to pending_or_paid ? order_path(order) : checkout_state_path(:payment)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Spree
|
2
|
+
module Wing
|
3
|
+
class BaseController < ::ApplicationController
|
4
|
+
before_action :wing_http_authenticate!
|
5
|
+
|
6
|
+
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
7
|
+
|
8
|
+
def wing_http_authenticate!
|
9
|
+
wing_payment_method = Spree::PaymentMethod.find_by(type: Spree::PaymentMethod::TYPE_WINGSDK)
|
10
|
+
|
11
|
+
authenticate_or_request_with_http_basic do |username, password|
|
12
|
+
return false unless wing_payment_method.present?
|
13
|
+
|
14
|
+
if wing_payment_method.preferred_basic_auth_username.blank? ||
|
15
|
+
wing_payment_method.preferred_basic_auth_password.blank?
|
16
|
+
return false
|
17
|
+
end
|
18
|
+
|
19
|
+
username == wing_payment_method.preferred_basic_auth_username &&
|
20
|
+
password == wing_payment_method.preferred_basic_auth_password
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def not_found
|
25
|
+
render json: { response_code: 404, response_msg: I18n.t(:resource_not_found, scope: 'spree.api') }, status: 404
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Spree
|
2
|
+
module Wing
|
3
|
+
class TransactionsController < BaseController
|
4
|
+
before_action :load_payment_source
|
5
|
+
def show
|
6
|
+
@transaction_status_response = Vpago::WingSdk::TransactionStatusResponse.new(@payment_source)
|
7
|
+
@transaction_status_response.call
|
8
|
+
|
9
|
+
render_result
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def load_payment_source
|
15
|
+
@payment_source = ::Spree::VpagoPaymentSource.find_by!(transaction_id: params[:id])
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_result
|
19
|
+
if @transaction_status_response.success?
|
20
|
+
render json: @transaction_status_response.result, status: 200
|
21
|
+
else
|
22
|
+
render json: { response_code: 422, response_msg: 'Unable to load response from wing' }, status: 422
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Spree
|
2
|
+
class WingRedirectsController < ApplicationController
|
3
|
+
layout 'wing'
|
4
|
+
before_action :load_payment, only: [:show]
|
5
|
+
|
6
|
+
def show
|
7
|
+
if @payment.present?
|
8
|
+
options = {
|
9
|
+
app_checkout: true
|
10
|
+
}
|
11
|
+
|
12
|
+
@client_redirect = ::Vpago::WingSdk::Checkout.new(@payment, options)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_payment
|
17
|
+
@payment = ::Spree::Payment.find_by(number: params[:payment_number])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Vpago
|
2
|
+
module Admin
|
3
|
+
module BaseHelperDecorator
|
4
|
+
def acleda_payment_card_options
|
5
|
+
{ '0 - XPAY': 0, '1 - Visa, Master Card, etc.': 1 }
|
6
|
+
end
|
7
|
+
|
8
|
+
# frontend should implement these in UI
|
9
|
+
def available_payment_icons
|
10
|
+
%w[
|
11
|
+
payway_abapay_khqr
|
12
|
+
payway_abapay
|
13
|
+
payway_alipay
|
14
|
+
payway_wechat
|
15
|
+
acleda
|
16
|
+
acleda_khqr
|
17
|
+
acleda_cards
|
18
|
+
cheque
|
19
|
+
payway_cards
|
20
|
+
wingpay
|
21
|
+
]
|
22
|
+
end
|
23
|
+
|
24
|
+
def preference_field_for(form, field, options)
|
25
|
+
case field
|
26
|
+
when 'preferred_acleda_type'
|
27
|
+
return form.select(:preferred_acleda_type, form.object.class::TYPES, {}, class: 'fullwidth select2')
|
28
|
+
when 'preferred_acleda_payment_card'
|
29
|
+
return form.select(:preferred_acleda_payment_card, acleda_payment_card_options, {},
|
30
|
+
class: 'fullwidth select2')
|
31
|
+
when 'preferred_icon_name'
|
32
|
+
return form.select(:preferred_icon_name, available_payment_icons, {}, class: 'fullwidth select2')
|
33
|
+
end
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Spree::Admin::BaseHelper.prepend(Vpago::Admin::BaseHelperDecorator)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { initializeApp } from "firebase/app";
|
2
|
+
import { getFirestore, doc, onSnapshot, setDoc } from "firebase/firestore";
|
3
|
+
|
4
|
+
async function listenToProcessingState({
|
5
|
+
firebaseConfigs,
|
6
|
+
orderNumber,
|
7
|
+
onPaymentIsProcessing,
|
8
|
+
onOrderIsProcessing,
|
9
|
+
onOrderIsCompleted,
|
10
|
+
onOrderProcessFailed,
|
11
|
+
onPaymentIsRefunded,
|
12
|
+
onPaymentProcessFailed,
|
13
|
+
onCompleted,
|
14
|
+
}) {
|
15
|
+
const app = initializeApp(firebaseConfigs);
|
16
|
+
const db = getFirestore(app);
|
17
|
+
|
18
|
+
const currentDate = new Date().toISOString().split("T")[0];
|
19
|
+
|
20
|
+
const documentRef = doc(db, "statuses", "cart", currentDate, orderNumber);
|
21
|
+
await setDoc(documentRef, { listening: true }, { merge: true });
|
22
|
+
|
23
|
+
onSnapshot(documentRef, (doc) => {
|
24
|
+
let documentData = doc.data();
|
25
|
+
|
26
|
+
let orderState = documentData["order_state"];
|
27
|
+
let paymentState = documentData["payment_state"];
|
28
|
+
let messageCode = documentData["message_code"];
|
29
|
+
let logMessage = documentData["log_message"];
|
30
|
+
|
31
|
+
let orderCompleted = orderState === "complete";
|
32
|
+
if (orderCompleted) {
|
33
|
+
onCompleted(orderState, paymentState);
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
|
37
|
+
switch (messageCode) {
|
38
|
+
case "payment_is_processing":
|
39
|
+
onPaymentIsProcessing(orderState, paymentState, logMessage);
|
40
|
+
break;
|
41
|
+
case "order_is_processing":
|
42
|
+
onOrderIsProcessing(orderState, paymentState, logMessage);
|
43
|
+
break;
|
44
|
+
case "order_is_completed":
|
45
|
+
onOrderIsCompleted(orderState, paymentState, logMessage);
|
46
|
+
break;
|
47
|
+
case "order_process_failed":
|
48
|
+
onOrderProcessFailed(orderState, paymentState, logMessage);
|
49
|
+
break;
|
50
|
+
case "payment_is_refunded":
|
51
|
+
onPaymentIsRefunded(orderState, paymentState, logMessage);
|
52
|
+
break;
|
53
|
+
case "payment_process_failed":
|
54
|
+
onPaymentProcessFailed(orderState, paymentState, logMessage);
|
55
|
+
break;
|
56
|
+
default:
|
57
|
+
break;
|
58
|
+
}
|
59
|
+
});
|
60
|
+
}
|
61
|
+
|
62
|
+
window.listenToProcessingState = listenToProcessingState;
|
@@ -0,0 +1 @@
|
|
1
|
+
class ApplicationUniqueJob < ActiveJob::Base; end
|
data/app/models/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Vpago
|
2
|
+
module Payoutable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :payouts, class_name: 'Spree::Payout', as: :payoutable
|
7
|
+
has_many :confirmed_payouts_for_vendor, -> { confirmed.where(default: false) },
|
8
|
+
class_name: 'Spree::Payout', as: :payoutable
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Spree
|
2
|
+
class Gateway::Acleda < PaymentMethod
|
3
|
+
preference :payment_expiry_time_in_mn, :integer
|
4
|
+
preference :host, :string
|
5
|
+
preference :login_id, :string
|
6
|
+
preference :password, :string
|
7
|
+
preference :merchant_id, :string
|
8
|
+
preference :merchant_name, :string
|
9
|
+
preference :signature, :string
|
10
|
+
preference :deeplink_partner_id, :string
|
11
|
+
preference :deeplink_data_encryption_key, :string
|
12
|
+
preference :success_url, :string
|
13
|
+
preference :error_url, :string
|
14
|
+
preference :other_url, :string
|
15
|
+
preference :acleda_company_name, :string
|
16
|
+
preference :acleda_payment_card, :integer
|
17
|
+
|
18
|
+
TYPES = %w[KHQR XPAY-MPGS].freeze
|
19
|
+
preference :acleda_type, :string
|
20
|
+
|
21
|
+
def xpay_mpgs?
|
22
|
+
preferred_acleda_type == 'XPAY-MPGS'
|
23
|
+
end
|
24
|
+
|
25
|
+
def khqr?
|
26
|
+
preferred_acleda_type == 'KHQR'
|
27
|
+
end
|
28
|
+
|
29
|
+
def payment_source_class
|
30
|
+
Spree::VpagoPaymentSource
|
31
|
+
end
|
32
|
+
|
33
|
+
def payment_profiles_supported?
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
# Custom PaymentMethod/Gateway can redefine this method to check method
|
38
|
+
# availability for concrete order.
|
39
|
+
def available_for_order?(_order)
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
# force to purchase instead of authorize
|
44
|
+
def auto_capture?
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def process(_money, _source, gateway_options)
|
49
|
+
Rails.logger.debug { "About to create payment for order #{gateway_options[:order_id]}" }
|
50
|
+
# First of all, invalidate all previous tranx orders to prevent multiple paid orders
|
51
|
+
# source.save!
|
52
|
+
ActiveMerchant::Billing::Response.new(true, 'Order created')
|
53
|
+
end
|
54
|
+
|
55
|
+
def cancel(_response_code)
|
56
|
+
# we can use this to send request to payment gateway api to cancel the payment ( void )
|
57
|
+
# currently Payway does not support to cancel the gateway
|
58
|
+
|
59
|
+
# in our case don't do anything
|
60
|
+
ActiveMerchant::Billing::Response.new(true, 'Acleda order has been cancelled.')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|