Reputation: 11
I'm trying to enable credit card billing in a rails app, and I receive the following error when trying to create the order: undefined method 'has_key?' for #<ActiveMerchant::Billing::CreditCard:0x244b3d8>
The referenced code is the purchase
method in the order model:
class Order < ActiveRecord::Base
...
include ActiveMerchant::Billing
...
def credit_card
@credit_card ||= ActiveMerchant::Billing::CreditCard.new(
:type => card_type,
:number => card_number,
:month => card_expires_on.month,
:year => card_expires_on.year,
:first_name => first_name,
:last_name => last_name,
:verification_value => card_verification
)
end
def purchase
response = GATEWAY.authorize(price_in_cents, credit_card)
if response.success?
GATEWAY.capture(price_in_cents, response.authorization)
cart.update_attribute(:purchased_at, Time.now)
else
raise StandardError, response.message
end
end
end
I'm using a Paypal Express gateway, for which the Active Merchant library defines purchase
as follows:
def purchase(money, options = {})
requires!(options, :token, :payer_id)
commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
end
private
def build_get_details_request(token)
xml = Builder::XmlMarkup.new :indent => 2
xml.tag! 'GetExpressCheckoutDetailsReq', 'xmlns' => PAYPAL_NAMESPACE do
xml.tag! 'GetExpressCheckoutDetailsRequest', 'xmlns:n2' => EBAY_NAMESPACE do
xml.tag! 'n2:Version', API_VERSION
xml.tag! 'Token', token
end
end
xml.target!
end
def build_sale_or_authorization_request(action, money, options)
currency_code = options[:currency] || currency(money)
xml = Builder::XmlMarkup.new :indent => 2
xml.tag! 'DoExpressCheckoutPaymentReq', 'xmlns' => PAYPAL_NAMESPACE do
xml.tag! 'DoExpressCheckoutPaymentRequest', 'xmlns:n2' => EBAY_NAMESPACE do
xml.tag! 'n2:Version', API_VERSION
xml.tag! 'n2:DoExpressCheckoutPaymentRequestDetails' do
xml.tag! 'n2:PaymentAction', action
xml.tag! 'n2:Token', options[:token]
xml.tag! 'n2:PayerID', options[:payer_id]
xml.tag! 'n2:PaymentDetails' do
xml.tag! 'n2:OrderTotal', localized_amount(money, currency_code), 'currencyID' => currency_code
# All of the values must be included together and add up to the order total
if [:subtotal, :shipping, :handling, :tax].all?{ |o| options.has_key?(o) }
xml.tag! 'n2:ItemTotal', localized_amount(options[:subtotal], currency_code), 'currencyID' => currency_code
xml.tag! 'n2:ShippingTotal', localized_amount(options[:shipping], currency_code),'currencyID' => currency_code
xml.tag! 'n2:HandlingTotal', localized_amount(options[:handling], currency_code),'currencyID' => currency_code
xml.tag! 'n2:TaxTotal', localized_amount(options[:tax], currency_code), 'currencyID' => currency_code
end
xml.tag! 'n2:NotifyURL', options[:notify_url]
xml.tag! 'n2:ButtonSource', application_id.to_s.slice(0,32) unless application_id.blank?
xml.tag! 'n2:InvoiceID', options[:order_id]
xml.tag! 'n2:OrderDescription', options[:description]
end
end
end
end
xml.target!
end
It looks like the credit_card
argument in my order model is being treated as the options
on which has_key?
is being called in the Active Merchant library, whose CreditCard
code doesn't define has_key?
. I'm using the latest version of Active Merchant.
Any help?
Upvotes: 1
Views: 1361
Reputation: 513
Looks like some gateways have a different purchase method.
TrustCommerceGateway (code showed on https://github.com/activemerchant/active_merchant)
def purchase(money, creditcard_or_billing_id, options = {})
PayPalExpressCheckoutGateway
def purchase(money, options = {})
So looks like you have to use PaypalGateway (and not PaypalExpressCheckoutGateway) if you want to use ActiveMerchant::Billing::CreditCard with Paypal
Upvotes: 1