Validate inclusion of payment method when saving PaymentOrder

This commit is contained in:
Karl Erik Õunapuu 2020-02-03 15:52:02 +02:00
parent 3f5b5962d1
commit ec5ff5dc8c
4 changed files with 71 additions and 64 deletions

View file

@ -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

View file

@ -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

View file

@ -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?

View file

@ -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,