class RefundPayments attr_accessor :order include RefundMethods def initialize(order, gift_card) @order = order @gift_card = gift_card end def perform!(payment_amount) sorted_payments = sorted_eligible_refund_payments(order.payments.completed) sorted_payments.each_with_object([]) do |payment, payments| break payments if payment_amount <= 0 next payments unless payment.can_credit? allowed_amount = [payment_amount, payment.credit_allowed].min payment_amount -= allowed_amount payments << { id: payment.id.to_s, amount: allowed_amount.to_s, status: 'PENDING', type: 'REFUND', gateway: payment.payment_method.type.demodulize, is_online: true, is_test: !Rails.env.match?(/production/), payment_details: transaction_payment_details(payment), created_at: Time.zone.now.iso8601(3) } end end private def sorted_eligible_refund_payments(payments) payments = payments.select { |p| eligible_refund_methods.include? p.payment_method.class } payments.sort_by { |p| eligible_refund_methods.index(p.payment_method.class) } end def transaction_payment_details(payment) details = {} details[:avs_result_code] = payment.avs_response if payment.avs_response.present? details[:cvv_result_code] = payment.cvv_response_code if payment.cvv_response_code.present? source = payment.source if source.respond_to?(:number) || source.respond_to?(:last_digits) details[:credit_card_number] = source.number || source.last_digits if source.number.present? || source.last_digits.present? details[:credit_card_company] = source.brand if source.brand.present? end details[:gift_card_id] = @gift_card.id if @gift_card.id.present? details[:gift_card_code] = @gift_card.code if @gift_card.code.present? details end end