Chapter 9

Hello,

I'm currently stunk on this issue for few days and I do not know how
to get it fixed.

The system always raises this error message :

order is closed

and here is my order.rb:

class Order < ActiveRecord::Base
include ActiveMerchant::Billing
  before_validation :set_status

attr_protected :id, :customer_ip, :status, :error_message, :updated_at, :created_at

attr_accessor :card_type, :card_number, :card_expiration_month, :card_expiration_year, :card_verification_value
  validates_size_of :order_items, :minimum => 1
  validates_length_of :ship_to_first_name, :in => 2..255
  validates_length_of :ship_to_last_name, :in => 2..255
  validates_length_of :ship_to_address, :in => 2..255
  validates_length_of :ship_to_city, :in => 2..255
  validates_length_of :ship_to_postal_code, :in => 2..255
  validates_length_of :ship_to_country, :in => 2..255
  validates_length_of :phone_number, :in => 7..20
  validates_length_of :customer_ip, :in => 7..15
  validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+
[a-z]{2,})$/i
  validates_inclusion_of :status, :in => %w(open processed closed
failed)

  validates_inclusion_of :card_type, :in => ['Visa', 'MasterCard',
'Discover'], :on => :create
  validates_length_of :card_number, :in => 13..19, :on => :create
  validates_inclusion_of :card_expiration_month, :in => %w(1 2 3 4 5 6
7 8 9 10 11 12), :on => :create
  validates_inclusion_of :card_expiration_year, :in => %w(2006 2007
2008 2009 2010 2017), :on => :create
  validates_length_of :card_verification_value, :in => 3..4, :on
=> :create

  has_many :order_items
  has_many :books, :through => :order_items
  def total
    order_items.inject(0) {|sum, n| n.price * n.amount + sum}
  end
  always

def process
     if closed? raise "Order is closed"
      begin
        process_with_active_merchant
      rescue => e
        logger.error("Order #{id} failed with error message #{e}")
        self.error_message = 'Error while processing order'
        self.status = 'failed'
      end
      save!
      self.status == 'processed'
     end
end

  def process_with_active_merchant
    Base.gateway_mode = :test
    gateway = PaypalGateway.new(
      :login => 'xxx_xxxxx_biz_api1.xxx.com',
      :password => 'xxxxxx',
            :pem => File.read(File.join(File.dirname(__FILE__), "../../
config/paypal/cert_key_pem.txt")))
      #:cert_path => File.join(File.dirname(__FILE__), "../../config/
paypal")

    gateway.connection.wiredump_dev = STDERR
    creditcard = CreditCard.new(
      :type => card_type,
      :number => card_number,
      :verification_value => card_verification_value,
      :month => card_expiration_month.to_i,
      :year => card_expiration_year.to_i,
      :first_name => ship_to_first_name,
      :last_name => ship_to_last_name
    )
    # Buyer information
    params = {
      :order_id => self.id,
      :email => email,
      :address => { :address1 => ship_to_address,
                    :city => ship_to_city,
                    :country => ship_to_country,
                    :zip => ship_to_postal_code
                  },
      :description => 'Books',
      :ip => customer_ip
    }
    response = gateway.purchase(total, creditcard, params)
    if response.success?
      self.status = 'processed'
    else
      self.error_message = response.message
      self.status = 'failed'
    end
  end
protected
  def set_status
    self.status = "open" if self.status.blank?
  end

end

I don't know what's wrong. Any help will be greatly appreciated.

Arte Fact

Well, that exception is obviously being raised in the first line of
#process. What do you get in your logs if you put this as the first line
in #process?

logger.debug "closed is '#{self.closed.inspect}'"

I assume closed? is returning true. I don't use ActiveMerchant so I am
not sure what closed is, but this should send you in the right direction.

-Bill

arte_fact wrote:

Hello Bill,

I tried it but I got an error message saying the the method
self.closed did not exist.

Thank you for your help.

Aret Fact

according to the source code's chapter 9 order.rb file at
http://www.apress.com/book/downloadfile/3200, this class also has this
instance method:

  def closed?
    status == 'closed'
  end

which wasn't included in the original posting. did you end up adding
this method to make the error message go away?

have you read or are in the process of reading the apress book,
_beginning ruby on rails e-commerce_ (by hellsten and laine),
particularly chapter 9: checkout and order processing ? if so,
perhaps you might be able to help..

this posting is a spin-off of the posting, http://tinyurl.com/29wx9t.

i encountered a similar problem as arte, despite including the order
class' closed? method.

to test the rest of the code without the condition if the status of
the order was closed (i believed i could safely assume it was 'open'
for the time being), i took out the following line:
           if closed? raise "Order is closed"
(with its corresponding 'end' statement.)

now a new problem arose, and in my development.log i see the following
error message:

"Order XX failed with undefined method `connection' for
#<ActiveMerchant::Billing::PaypalGateway:0x3211c38>"

that was prompted by the rescue instructions,
logger.error("Order #{id} failed with error message #{e}")

so i tried looking for this so-called string/method/reference to
'connection' in the vendor/plugins/active_merchant/lib/active_merchant/
billing/gateways/paypal files, particularly in the PaypalGateway
class, but to no avail :frowning:

i am confused. is it possible it is looking for 'connection' through
other components that do exist in the PaypalGateway class contents
or ?

if interested or it would be helpful, the source code for this chapter
9 (and others) in this book are available here:
http://www.apress.com/book/downloadfile/3200