module Piggybak class Payment < ActiveRecord::Base belongs_to :order belongs_to :payment_method validates_presence_of :status validates_presence_of :total validates_presence_of :payment_method_id validates_presence_of :month validates_presence_of :year attr_accessor :number attr_accessor :verification_value def status_enum ["paid", "refunded"] end def month_enum 1.upto(12) end def year_enum Time.now.year.upto(Time.now.year + 10) end def credit_card { "number" => self.number, "month" => self.month, "year" => self.year, "verification_value" => self.verification_value, "first_name" => self.order.billing_address.firstname, "last_name" => self.order.billing_address.lastname } end def process ActiveMerchant::Billing::Base.mode = Piggybak.config.activemerchant_mode if self.new_record? payment_gateway = self.payment_method.klass.constantize gateway = payment_gateway::KLASS.new(self.payment_method.key_values) credit_card = ActiveMerchant::Billing::CreditCard.new(self.credit_card) gateway_response = gateway.authorize(self.order.total_due*100, credit_card, :address => self.order.avs_address) if gateway_response.success? self.attributes = { :total => self.order.total_due, :transaction_id => payment_gateway.transaction_id(gateway_response) } gateway.capture(1000, gateway_response.authorization) return true else self.errors.add :payment_method_id, gateway_response.message return false end else return true end end # TODO: Add refund support at some point # Note: It is not added now, because for methods that do not store # user profiles, a credit card number must be passed # If encrypted credit cards are stored on the system, # this can be updated def refund =begin # ActiveMerchant::Billing::Base.mode = Piggybak.config.activemerchant_mode begin payment_gateway = self.payment_method.klass.constantize gateway = payment_gateway::KLASS.new(self.payment_method.key_values) b = gateway.refund(self.total*100, self.transaction_id, { :card_number => "4111111111111111" }) rescue Exception => e return e.inspect end =end self.update_attribute(:status, "refunded") self.order.update_attribute(:total_due, self.order.total_due + self.total) return "Marked as Refunded" end def admin_label if !self.new_record? return "Payment ##{self.id} (#{self.created_at.strftime("%m-%d-%Y")})
" + "Payment Method: #{self.payment_method.description}
" + "Status: #{self.status}
" + "Transaction ID: #{self.transaction_id}
" + "$#{"%.2f" % self.total}" else return "" end end alias :details :admin_label validates_each :payment_method_id do |record, attr, value| if record.new_record? credit_card = ActiveMerchant::Billing::CreditCard.new(record.credit_card) if !credit_card.valid? credit_card.errors.each do |key, value| if value.any? && !["first_name", "last_name", "type"].include?(key) record.errors.add key, (value.is_a?(Array) ? value.join(', ') : value) end end end end end end end