diff --git a/app/controllers/registrar/payments_controller.rb b/app/controllers/registrar/payments_controller.rb index 00b10f34e..736cfe01c 100644 --- a/app/controllers/registrar/payments_controller.rb +++ b/app/controllers/registrar/payments_controller.rb @@ -28,7 +28,7 @@ class Registrar @payment_order.update!(response: params.to_unsafe_h) if @payment_order.payment_received? - @payment_order.complete_transaction(@payment_order.composed_transaction) + @payment_order.complete_transaction if @payment_order.invoice.paid? flash[:notice] = t(:pending_applied) @@ -65,7 +65,8 @@ class Registrar end def supported_payment_method? - PaymentOrder.supported_method?(params[:bank]) + method_name = PaymentOrder.type_from_shortname(params[:bank]) + PaymentOrder.supported_method?(method_name) end end end diff --git a/app/models/payment_order.rb b/app/models/payment_order.rb index 4ce67d887..e204ec5dc 100644 --- a/app/models/payment_order.rb +++ b/app/models/payment_order.rb @@ -9,48 +9,13 @@ class PaymentOrder < ApplicationRecord belongs_to :invoice, optional: false validate :invoice_cannot_be_already_paid, on: :create - # validates :type, inclusion: { in: PAYMENT_METHODS } + validate :supported_payment_method enum status: { issued: 'issued', paid: 'paid', cancelled: 'cancelled', failed: 'failed' } attr_accessor :return_url, :response_url - # Name of configuration namespace - def self.config_namespace_name; end - - def invoice_cannot_be_already_paid - return unless invoice&.paid? - - errors.add(:invoice, 'is already paid') - end - - def self.type_from_shortname(shortname) - ('PaymentOrders::' + shortname.camelize).constantize - end - - def self.supported_method?(some_class) - supported_methods.include? type_from_shortname(some_class) - rescue NameError - false - end - - def complete_transaction(transaction) - paid! - - transaction.save! - transaction.bind_invoice(invoice.number) - - return unless transaction.errors.any? - - worded_errors = 'Failed to bind. ' - transaction.errors.full_messages.each do |err| - worded_errors << "#{err}, " - end - - update!(notes: worded_errors) - end - def self.supported_methods supported = [] @@ -64,6 +29,59 @@ class PaymentOrder < ApplicationRecord supported end + # Name of configuration namespace + def self.config_namespace_name; end + + def supported_payment_method + return if PaymentOrder.supported_method? type.constantize + + errors.add(:type, 'is not supported') + end + + def invoice_cannot_be_already_paid + return unless invoice&.paid? + + errors.add(:invoice, 'is already paid') + end + + def self.type_from_shortname(shortname) + ('PaymentOrders::' + shortname.camelize).constantize + end + + def self.supported_method?(some_class) + supported_methods.include? some_class + rescue NameError + false + end + + def base_transaction(sum:, paid_at:, buyer_name:) + BankTransaction.new( + description: invoice.order, + reference_no: invoice.reference_no, + currency: invoice.currency, + iban: invoice.seller_iban, + sum: sum, + paid_at: paid_at, + buyer_name: buyer_name + ) + end + + def complete_transaction + paid! + transaction = composed_transaction + transaction.save! + transaction.bind_invoice(invoice.number) + + return unless transaction.errors.any? + + worded_errors = 'Failed to bind. ' + transaction.errors.full_messages.each do |err| + worded_errors << "#{err}, " + end + + update!(notes: worded_errors) + end + def channel type.gsub('PaymentOrders::', '') end diff --git a/app/models/payment_orders/bank_link.rb b/app/models/payment_orders/bank_link.rb index c5a8bc54e..5bfd02c48 100644 --- a/app/models/payment_orders/bank_link.rb +++ b/app/models/payment_orders/bank_link.rb @@ -53,25 +53,20 @@ module PaymentOrders end def create_failure_report - notes = "User failed to make valid payment. Bank responded with code #{response['VK_SERVICE']}" + notes = "User failed to make payment. Bank responded with code #{response['VK_SERVICE']}" status = 'cancelled' update!(notes: notes, status: status) end def composed_transaction - transaction = BankTransaction.where(description: invoice.order).first_or_initialize( - description: invoice.order, - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) + paid_at = Time.parse(response['VK_T_DATETIME']) + transaction = base_transaction(sum: response['VK_AMOUNT'], + paid_at: paid_at, + buyer_name: response['VK_SND_NAME']) - transaction.sum = response['VK_AMOUNT'] - transaction.bank_reference = response['VK_T_NO'] + transaction.bank_reference = response['VK_T_NO'] transaction.buyer_bank_code = response['VK_SND_ID'] - transaction.buyer_iban = response['VK_SND_ACC'] - transaction.buyer_name = response['VK_SND_NAME'] - transaction.paid_at = Time.parse(response['VK_T_DATETIME']) + transaction.buyer_iban = response['VK_SND_ACC'] transaction end @@ -80,7 +75,7 @@ module PaymentOrders response['VK_SERVICE'] == SUCCESSFUL_PAYMENT_SERVICE_NUMBER end - # private + private def valid_successful_transaction? valid_success_notice? && valid_amount? && valid_currency? diff --git a/app/models/payment_orders/every_pay.rb b/app/models/payment_orders/every_pay.rb index 53705d1a6..2f848fa82 100644 --- a/app/models/payment_orders/every_pay.rb +++ b/app/models/payment_orders/every_pay.rb @@ -5,7 +5,7 @@ module PaymentOrders ACCOUNT_ID = ENV['payments_every_pay_seller_account'] SUCCESSFUL_PAYMENT = %w[settled authorized].freeze - CONFIG_NAMESPACE = 'every_pay' + CONFIG_NAMESPACE = 'every_pay'.freeze def self.config_namespace_name CONFIG_NAMESPACE @@ -39,18 +39,9 @@ module PaymentOrders end def composed_transaction - transaction = BankTransaction.new( - description: invoice.order, - reference_no: invoice.reference_no, - currency: invoice.currency, - iban: invoice.seller_iban - ) - - transaction.sum = response['amount'] - transaction.paid_at = Date.strptime(response['timestamp'], '%s') - transaction.buyer_name = response['cc_holder_name'] - - transaction + base_transaction(sum: response['amount'], + paid_at: Date.strptime(response['timestamp'], '%s'), + buyer_name: response['cc_holder_name']) end def create_failure_report @@ -59,6 +50,8 @@ module PaymentOrders update!(notes: notes, status: status) end + private + def base_params { api_username: USER,