Skip to content

Commit

Permalink
Refactor callback service and controller
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulDoyle-DEFRA committed Jun 21, 2022
1 parent 02d0c3e commit 3538517
Show file tree
Hide file tree
Showing 69 changed files with 2,180 additions and 94 deletions.
95 changes: 95 additions & 0 deletions app/controllers/waste_carriers_engine/govpay_forms_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# frozen_string_literal: true

module WasteCarriersEngine
class GovpayFormsController < ::WasteCarriersEngine::FormsController
include UnsubmittableForm

def new
super(GovpayForm, "govpay_form")

payment_info = prepare_for_payment

if payment_info == :error
flash[:error] = I18n.t(".waste_carriers_engine.govpay_forms.new.setup_error")
go_back
else
redirect_to payment_info[:url]
end
end

def payment_callback
find_or_initialize_transient_registration(params[:token])

if @transient_registration.finance_details.orders.first.govpay_status == "success"
Rails.logger.warn "Attempt to pay for an order with govpay_status already set to success"
respond_to_acceptable_payment(:success)

else
@transient_registration.with_lock do
payment_status = GovpayCallbackService.new(params[:uuid]).run

case payment_status
when :success, :pending
respond_to_acceptable_payment(payment_status)
else
respond_to_unsuccessful_payment(payment_status)
end
end
end
rescue ArgumentError
Rails.logger.warn "Govpay payment callback error: invalid payment uuid \"#{params[:uuid]}\""
Airbrake.notify("Govpay callback error", "Invalid payment uuid \"#{params[:uuid]}\"")
flash[:error] = I18n.t(".waste_carriers_engine.govpay_forms.new.internal_error")
go_back
end

private

def prepare_for_payment
@transient_registration.prepare_for_payment(:govpay, current_user)
order = @transient_registration.finance_details.orders.first
govpay_service = GovpayPaymentService.new(@transient_registration, order, current_user)
govpay_service.prepare_for_payment
end

def respond_to_acceptable_payment(action)
return unless valid_transient_registration?

if action != :error
log_and_send_govpay_response(true, action)
@transient_registration.next!
redirect_to_correct_form
else
log_and_send_govpay_response(false, action)
flash[:error] = I18n.t(".waste_carriers_engine.govpay_forms.#{action}.invalid_response")
go_back
end
end

def respond_to_unsuccessful_payment(action)
return unless valid_transient_registration?

if action != :error
log_and_send_govpay_response(true, action)
flash[:error] = I18n.t(".waste_carriers_engine.govpay_forms.#{action}.message")
else
log_and_send_govpay_response(false, action)
flash[:error] = I18n.t(".waste_carriers_engine.govpay_forms.#{action}.invalid_response")
end

go_back
end

def valid_transient_registration?
setup_checks_pass?
end

def log_and_send_govpay_response(is_valid, action)
valid_text = is_valid ? "Valid" : "Invalid"
title = "#{valid_text} Govpay response: #{action}"

Rails.logger.debug [title, "Params:", params.to_json].join("\n")
Airbrake.notify(title, error_message: params) unless is_valid && action == :success
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module WasteCarriersEngine
class RegistrationReceivedPendingGovpayPaymentFormsController < ::WasteCarriersEngine::FormsController
include UnsubmittableForm
include CannotGoBackForm

def new
return unless super(
RegistrationReceivedPendingGovpayPaymentForm,
"registration_received_pending_govpay_payment_form"
)

begin
@registration = RegistrationCompletionService.run(@transient_registration)
rescue StandardError => e
Airbrake.notify(e, reg_identifier: @transient_registration.reg_identifier)
Rails.logger.error e
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module WasteCarriersEngine
class RenewalReceivedPendingGovpayPaymentFormsController < ::WasteCarriersEngine::FormsController
include CannotGoBackForm
include UnsubmittableForm

def new
super(RenewalReceivedPendingGovpayPaymentForm, "renewal_received_pending_govpay_payment_form")
end
end
end
9 changes: 9 additions & 0 deletions app/forms/waste_carriers_engine/govpay_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

module WasteCarriersEngine
class GovpayForm < ::WasteCarriersEngine::BaseForm
def self.can_navigate_flexibly?
false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module WasteCarriersEngine
class RegistrationReceivedPendingGovpayPaymentForm < ::WasteCarriersEngine::BaseForm
include CannotSubmit

def self.can_navigate_flexibly?
false
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

module WasteCarriersEngine
class RenewalReceivedPendingGovpayPaymentForm < ::WasteCarriersEngine::BaseForm
include CannotSubmit

def self.can_navigate_flexibly?
false
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,16 @@ def ad_contact_email?
contact_email.blank? || contact_email == WasteCarriersEngine.configuration.assisted_digital_email
end

def pending_worldpay_payment?
def pending_online_payment?
return false unless finance_details.present? &&
finance_details.orders.present? &&
finance_details.orders.first.present?

WorldpayValidatorService.valid_world_pay_status?(:pending, finance_details.orders.first.world_pay_status)
if WasteCarriersEngine::FeatureToggle.active?(:govpay_payments)
GovpayValidatorService.valid_govpay_status?(:pending, finance_details.orders.first.govpay_status)
else
WorldpayValidatorService.valid_world_pay_status?(:pending, finance_details.orders.first.world_pay_status)
end
end

# Some business types should not have a company_no
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ module CanUseNewRegistrationWorkflow
state :cards_form
state :payment_summary_form
state :worldpay_form
state :govpay_form
state :confirm_bank_transfer_form

state :registration_completed_form
state :registration_received_pending_payment_form
state :registration_received_pending_conviction_form
state :registration_received_pending_worldpay_payment_form
state :registration_received_pending_govpay_payment_form

# Transitions
event :next do
Expand Down Expand Up @@ -264,6 +266,9 @@ module CanUseNewRegistrationWorkflow
# Payment & Completion
transitions from: :cards_form, to: :payment_summary_form

transitions from: :payment_summary_form, to: :govpay_form,
if: :paying_by_card_govpay?

transitions from: :payment_summary_form, to: :worldpay_form,
if: :paying_by_card?

Expand All @@ -274,13 +279,15 @@ module CanUseNewRegistrationWorkflow
# callback block, hence we went for `after`
after: :set_metadata_route

transitions from: :worldpay_form, to: :registration_received_pending_worldpay_payment_form,
if: :pending_worldpay_payment?,
transitions from: :worldpay_form,
to: :registration_received_pending_worldpay_payment_form,
if: :pending_online_payment?,
# TODO: This don't get triggered if in the `success`
# callback block, hence we went for `after`
after: :set_metadata_route

transitions from: :worldpay_form, to: :registration_received_pending_conviction_form,
transitions from: :worldpay_form,
to: :registration_received_pending_conviction_form,
if: :conviction_check_required?,
# TODO: This don't get triggered if in the `success`
# callback block, hence we went for `after`
Expand All @@ -290,6 +297,19 @@ module CanUseNewRegistrationWorkflow
# TODO: This don't get triggered if in the `success`
# callback block, hence we went for `after`
after: :set_metadata_route

transitions from: :govpay_form,
to: :registration_received_pending_govpay_payment_form,
if: :pending_online_payment?,
after: :set_metadata_route

transitions from: :govpay_form,
to: :registration_received_pending_conviction_form,
if: :conviction_check_required?,
after: :set_metadata_route

transitions from: :govpay_form, to: :registration_completed_form,
after: :set_metadata_route
end

# Transitions
Expand Down Expand Up @@ -366,6 +386,10 @@ def paying_by_card?
temp_payment_method == "card"
end

def paying_by_card_govpay?
WasteCarriersEngine::FeatureToggle.active?(:govpay_payments) && temp_payment_method == "card"
end

def switch_to_lower_tier
update_attributes(tier: WasteCarriersEngine::NewRegistration::LOWER_TIER)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,14 @@ module CanUseRenewingRegistrationWorkflow
state :cards_form
state :payment_summary_form
state :worldpay_form
state :govpay_form
state :confirm_bank_transfer_form

state :renewal_complete_form
state :renewal_received_pending_conviction_form
state :renewal_received_pending_payment_form
state :renewal_received_pending_worldpay_payment_form
state :renewal_received_pending_govpay_payment_form

state :cannot_renew_type_change_form

Expand Down Expand Up @@ -193,14 +195,17 @@ module CanUseRenewingRegistrationWorkflow
# Payment & completion
transitions from: :cards_form, to: :payment_summary_form

transitions from: :payment_summary_form, to: :govpay_form,
if: :paying_by_card_govpay?

transitions from: :payment_summary_form, to: :worldpay_form,
if: :paying_by_card?

transitions from: :payment_summary_form, to: :confirm_bank_transfer_form

transitions from: :worldpay_form, to: :renewal_received_pending_worldpay_payment_form,
if: :pending_worldpay_payment?,
success: :send_renewal_pending_worldpay_payment_email,
if: :pending_online_payment?,
success: :send_renewal_pending_online_payment_email,
# TODO: This don't get triggered if in the `success`
# callback block, hence we went for `after`
after: :set_metadata_route
Expand All @@ -217,6 +222,19 @@ module CanUseRenewingRegistrationWorkflow
# callback block, hence we went for `after`
after: :set_metadata_route

transitions from: :govpay_form, to: :renewal_received_pending_govpay_payment_form,
if: :pending_online_payment?,
success: :send_renewal_pending_online_payment_email,
after: :set_metadata_route

transitions from: :govpay_form, to: :renewal_received_pending_conviction_form,
if: :conviction_check_required?,
success: :send_renewal_pending_checks_email,
after: :set_metadata_route

transitions from: :govpay_form, to: :renewal_complete_form,
after: :set_metadata_route

transitions from: :confirm_bank_transfer_form, to: :renewal_received_pending_payment_form,
success: :send_renewal_received_pending_payment_email,
# TODO: This don't get triggered if in the `success`
Expand Down Expand Up @@ -279,6 +297,10 @@ def paying_by_card?
temp_payment_method == "card"
end

def paying_by_card_govpay?
WasteCarriersEngine::FeatureToggle.active?(:govpay_payments) && temp_payment_method == "card"
end

def use_trading_name?
temp_use_trading_name == "yes"
end
Expand All @@ -287,8 +309,8 @@ def incorrect_company_data?
temp_use_registered_company_details == "no"
end

def send_renewal_pending_worldpay_payment_email
WasteCarriersEngine::Notify::RenewalPendingWorldpayPaymentEmailService.run(registration: self)
def send_renewal_pending_online_payment_email
WasteCarriersEngine::Notify::RenewalPendingOnlinePaymentEmailService.run(registration: self)
rescue StandardError => e
Airbrake.notify(e, registration_no: reg_identifier) if defined?(Airbrake)
end
Expand Down
7 changes: 2 additions & 5 deletions app/models/waste_carriers_engine/finance_details.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ class FinanceDetails

field :balance, type: Integer

validates :balance,
presence: true
validates :balance, presence: true

def self.new_renewal_finance_details(transient_registration, method, current_user)
user_email = current_user&.email || transient_registration.contact_email
Expand Down Expand Up @@ -43,9 +42,7 @@ def zero_difference_balance

def update_balance
order_balance = orders.sum { |item| item[:total_amount] }
# Select payments where the type is not WORLDPAY, or if it is, the status is AUTHORISED
payment_balance = payments.any_of({ :payment_type.ne => "WORLDPAY" },
world_pay_payment_status: "AUTHORISED").sum { |item| item[:amount] }
payment_balance = payments.except_online_not_authorised.sum { |item| item[:amount] }
self.balance = order_balance - payment_balance
end
end
Expand Down
19 changes: 17 additions & 2 deletions app/models/waste_carriers_engine/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ class Order
field :orderCode, as: :order_code, type: String
field :paymentMethod, as: :payment_method, type: String
field :merchantId, as: :merchant_id, type: String
field :payment_uuid, type: String
field :totalAmount, as: :total_amount, type: Integer
field :currency, type: String
field :dateCreated, as: :date_created, type: DateTime
field :worldPayStatus, as: :world_pay_status, type: String
field :govpayId, as: :govpay_id, type: String
field :govpayStatus, as: :govpay_status, type: String
field :dateLastUpdated, as: :date_last_updated, type: DateTime
field :updatedByUser, as: :updated_by_user, type: String
field :description, type: String
Expand Down Expand Up @@ -78,12 +81,24 @@ def set_description
self.description = generate_description
end

def update_after_worldpay(status)
self.world_pay_status = status
def update_after_online_payment(status)
if WasteCarriersEngine::FeatureToggle.active?(:govpay_payments)
Rails.logger.debug "Updating order after online payment, status: #{status}"
self.govpay_status = status
else
self.world_pay_status = status
end
self.date_last_updated = Time.current
save!
end

# Generate a uuid for the payment associated with this order, on demand
def payment_uuid
update_attributes!(payment_uuid: SecureRandom.uuid) unless self[:payment_uuid]

self[:payment_uuid]
end

private

def generate_description
Expand Down
Loading

0 comments on commit 3538517

Please sign in to comment.