From: Cleverlemming Date: 2011-12-11T09:16:05+09:00 Subject: Scope and Instance Variable Question Hail Caesars! I'm wondering why the instance variable "@spree_invoice_number" is out of scope in both the authorize and the create_transaction methods in the appended code. Both of the aforementioned methods are called after the create_profile method, where the instance variable is initialized. I checked to make sure the instance variable name is unique in both the application and the gem repository. Thanks in advance for any suggestions! ---------------- class Gateway::AuthorizeNetCim < Gateway #unabridged version of this file is here: https://gist.github.com/1454271 attr_accessor :spree_invoice_number def provider_class self.class end def options # add :test key in the options hash, as that is what the ActiveMerchant::Billing::AuthorizeNetGateway expects if self.prefers? :test_mode self.class.default_preferences[:test] = true else self.class.default_preferences.delete(:test) end super end def authorize(amount, creditcard, gateway_options) create_transaction(amount, creditcard, :auth_only ) # spree_invoice_number is nil within this method: # create_transaction(amount, creditcard, :auth_only, :order => {:invoice_number => @spree_invoice_number} ) end # Create a new CIM customer profile ready to accept a payment def create_profile(payment) @spree_invoice_number = payment.order.number if payment.source.gateway_customer_profile_id.nil? profile_hash = create_customer_profile(payment) logger.debug("create_profile @spree_invoice number: #{@spree_invoice_number}\n" ) profile_hash[:customer_address_id] = create_customer_shipping_profile(profile_hash[:customer_profile_id], payment) payment.source.update_attributes(:gateway_customer_profile_id => profile_hash[:customer_profile_id], :gateway_payment_profile_id => profile_hash[:customer_payment_profile_id], :address_id => profile_hash[:customer_address_id], :invoice_number => @spree_invoice_number ) end #successfully prints variable to log can_access_instance_variable_here end # simpler form def create_profile_from_card(card) if card.gateway_customer_profile_id.nil? profile_hash = create_customer_profile(card) card.update_attributes(:gateway_customer_profile_id => profile_hash[:customer_profile_id]) end end def can_access_instance_variable_here logger.debug("can_access_instance_variable_here @spree_invoice number: #{@spree_invoice_number}\n" ) end private # Create a transaction on a creditcard # Set up a CIM profile for the card if one doesn't exist # Valid transaction_types are :auth_only, :capture_only and :auth_capture def create_transaction(amount, creditcard, transaction_type, options = {}) #create_profile(creditcard, creditcard.gateway_options) creditcard.save if amount amount = "%.2f" % (amount/100.0) # This gateway requires formated decimal, not cents end transaction_options = { :type => transaction_type, :amount => amount, :customer_profile_id => creditcard.gateway_customer_profile_id, :customer_payment_profile_id => creditcard.gateway_payment_profile_id, :order => {:invoice_number => @spree_invoice_number } }.update(options) #spree_invoice_number is nil here logger.debug("inside create_transaction: #{transaction_options.inspect}\n" ) t = cim_gateway.create_customer_profile_transaction(:transaction => transaction_options) logger.debug("\nAuthorize Net CIM Transaction") logger.debug(" transaction_options: #{transaction_options.inspect}") #spree_invoice_number is nil here also logger.debug(" response: #{t.inspect}\n") #instance variable is nil when can_access_instance_variable_here called from this method: can_access_instance_variable_here t end # Create a new CIM customer profile ready to accept a payment # now creates shipping address profile def create_customer_profile(payment) options = options_for_create_customer_profile(payment) response = cim_gateway.create_customer_profile(options) if response.success? customer_profile_hash = { :customer_profile_id => response.params["customer_profile_id"], :customer_payment_profile_id => response.params["customer_payment_profile_id_list"].values.first } return customer_profile_hash else payment.gateway_error(response) if payment.respond_to? :gateway_error payment.source.gateway_error(response) end end def options_for_create_customer_profile(payment) if payment.is_a? Creditcard info = { :bill_to => generate_address_hash(payment.address), :payment => { :credit_card => payment }} else info = { :bill_to => generate_address_hash(payment.order.bill_address), :payment => { :credit_card => payment.source } } end validation_mode = preferred_validate_on_profile_create ? preferred_server.to_sym : :none { :profile => { :merchant_customer_id => "#{Time.now.to_f}", #:ship_to_list => generate_address_hash(creditcard.checkout.ship_address), :payment_profiles => info }, :validation_mode => validation_mode } end def cim_gateway ActiveMerchant::Billing::Base.gateway_mode = preferred_server.to_sym gateway_options = options ActiveMerchant::Billing::AuthorizeNetCimGateway.new(gateway_options) end end