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