Skip to content
This repository has been archived by the owner on Nov 29, 2019. It is now read-only.

Capturing payment through spree admin fails (works on paypal) #54

Closed
steveroot opened this issue May 4, 2012 · 24 comments · Fixed by #66
Closed

Capturing payment through spree admin fails (works on paypal) #54

steveroot opened this issue May 4, 2012 · 24 comments · Fixed by #66

Comments

@steveroot
Copy link

Processing my first test orders, using both providors:
Spree::BillingIntegration::PaypalExpress
Spree::BillingIntegration::PaypalExpressUk

Order processes fine, customer returned to spree confirmation page.

Using the 'capture' button in spree admin, error displayed:

ArgumentError in Spree::Admin::PaymentsController#fire

wrong number of arguments (3 for 1)
Rails.root: /Users/steve/Documents/ruby/rkbbspree

Application Trace | Framework Trace | Full Trace
activesupport (3.2.2) lib/active_support/core_ext/kernel/reporting.rb:68:in `capture'

However, the payment can be accepted through the paypal interface and solving this is probably beyond my coding ability right now.
If it's working for others, perhaps this is to do with the currency being in GBP but the Sandbox dev account is USD (I don't recall the option to change). When accepting the payment through paypal I had to decide whether to keep in GBP or currency convert to USD.

@mraaroncruz
Copy link

I am getting this too
the problem code

# in spree app/models/spree/payment/processing.rb
      def capture!
        protect_from_connection_error do
          check_environment

          if payment_method.payment_profiles_supported?
            # Gateways supporting payment profiles will need access to creditcard object because this stores the payment profile information
            # so supply the authorization itself as well as the creditcard, rather than just the authorization code
            response = payment_method.capture(self, source, gateway_options)
          else
            # Standard ActiveMerchant capture usage
            #HERE
            response = payment_method.capture((amount * 100).round,
                                              response_code,
                                              gateway_options)
          end

          handle_response(response, :complete, :failure)
        end
      end
# in spree_paypal_express/app/models/spree/paypal_account.rb
  def capture(payment)
    authorization = find_authorization(payment) 
    ppx_response = payment.payment_method.provider.capture(amount_in_cents(payment.amount), authorization.params["transaction_id"], :currency => payment.payment_method.preferred_currency)
    if ppx_response.success?
      record_log payment, ppx_response
      payment.complete
    else
      gateway_error(ppx_response.message)
    end

  end

thanks

@imme5150
Copy link

Same issue here, I think:

A ArgumentError occurred in payments#fire:

wrong number of arguments (3 for 1)
vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.3/lib/active_support/core_ext/kernel/reporting.rb:68:in 'capture'
vendor/bundle/ruby/1.9.1/gems/spree_core-1.1.0/app/models/spree/payment/processing.rb:40:in 'block in capture!'
vendor/bundle/ruby/1.9.1/gems/spree_core-1.1.0/app/models/spree/payment/processing.rb:146:in 'protect_from_connection_error'
vendor/bundle/ruby/1.9.1/gems/spree_core-1.1.0/app/models/spree/payment/processing.rb:31:in 'capture!'
vendor/bundle/ruby/1.9.1/gems/spree_core-1.1.0/app/controllers/spree/admin/payments_controller.rb:58:in 'fire'

@bvpb
Copy link

bvpb commented May 23, 2012

Same issue for me too.

@sbounmy
Copy link

sbounmy commented May 30, 2012

Same issue here.

@pferdefleisch looks like the paypalaccount#capture is never called by payment_method.capture...

I'm investigating now..

@msevestre
Copy link

Same issue. Any news on the PR?

@msevestre
Copy link

using code from branch custom '7417b80'. I get following error when capturing a payment
The transaction id is not valid

@sbounmy
Copy link

sbounmy commented Jun 7, 2012

hi @msevestre, can you be more precise please?

  • where do you capture the payment, from the admin or during checkout ?
  • can you check 'review' in paypal payment method to see if it solve the issue ?

@msevestre
Copy link

  • Payment was captured in the admin section
  • When review is unchecked, the issue is a described above
  • When review is checked however, something else goes wrong. Although the order was confirmed in the front end, there is no payment associated with the order! Hence payment capture is in that case impossible (maybe this is solved in PR Setting the order.state to 'confirm' if in paypal_confirm view #61)

I have a lot of customization happening in my site. I will create a new spree site and use the custom branch of the paypal extension to tes that issue again. I'll get back to you asap to let you know if the issue is still present.

@msevestre
Copy link

I just created a new site using spree 1.1.1 and commit 7417b80.

  • When review is unchecked, I get the same error
    the transaction id is not valid
  • When review is checked, I get this time another error
ArgumentError in Spree/checkout#paypal_confirm
comparison of Fixnum with nil failed

   <div class="row" data-hook="checkout_header">
     <h1 class="columns three alpha" data-hook="checkout_title"><%= t(:checkout) %></h1>
     <div class="columns thirteen omega" data-hook="checkout_progress"><%= checkout_progress %></div>
   </div>

 <p>

Would be happy to help more but I am not sure how...

@msevestre
Copy link

I investigated a bit more to understand what is going on:

In spree core we have following code

# in spree app/models/spree/payment/processing.rb
def capture!
     protect_from_connection_error do
     check_environment

     if payment_method.payment_profiles_supported?
     # ....
        response = payment_method.capture(self, source, gateway_options)
     else
        # Standard ActiveMerchant capture usage
          response = payment_method.capture((amount * 100).round,
                                              response_code,
                                              gateway_options)
     end
    #....
  • If review is unchecked, the code in the extensions returns false for payment_profiles_supported?
    That means that this code is being executed:
    response = payment_method.capture((amount * 100).round, response_code, gateway_options)
    which leads in 7417b80 to a call to the method capture from class Spree::BillingIntegration::PaypalExpressBase
  • Since the payment_or amount is not a Spree::Payment but a float, the wrong transaction_id is being passed to the provider using provider.capture(payment_or_amount, account_or_response_code, :currency => preferred_currency)

It's all really confusing. One thing is sure. The code from the official extension cannot work. The class PaypalAccount is not used when capturing a payment. I think your implementation using ``Spree::BillingIntegration::PaypalExpressBase` goes in the good direction.

@sbounmy
Copy link

sbounmy commented Jun 8, 2012

@msevestre, sorry for the late response and thanks for investigating!

I've tested with review checked and it is working for me, but would definitely help to you to find what's wrong with 'comparison of Fixnum with nil failed'
With review unchecked, I didn't get a chance to test it yet and needed some feedback.
Maybe @radar could put us in the right track on how to handle the 'Standard ActiveMerchant capture usage'

@samhamilton
Copy link

Same issue for me too.

@radar
Copy link

radar commented Jun 20, 2012

I don't know the answer to this one sorry. If someone else can investigate and submit a patch, I can review.

@BDQ
Copy link

BDQ commented Jul 17, 2012

I'm taking a look at this PR, it appears to be a little more broken by some recent changes in spree but overall has some decent improvements.

@nchatu
Copy link

nchatu commented Jul 19, 2012

I am getting the same error when capturing the payment from the admin with both Spree::BillingIntegration::PaypalExpress and Spree::BillingIntegration::PaypalExpressUk

@cwise
Copy link

cwise commented Jul 19, 2012

+1 for this. We are running into the original problem up top with the confusion between capture for a Spree::Creditcard object and capture in ActiveSupport. This has gotta be a show-stopper for anyone using 1.1.1.

@cwise
Copy link

cwise commented Jul 19, 2012

The problem at the very top of this list is that capture didn't exist in Creditcard, but does exist in CreditCard. How did it used to work? Anyone using on older gateway, how did you complete payments?

@BDQ
Copy link

BDQ commented Jul 20, 2012

I've just pushed fixes to 1-1-stable and master, and everything is working for me with a 1.1.2 based stored.

I've also fixed the majority of broken specs.

Please test and open tickets for anything specific thats still broken. Thanks!

@BDQ BDQ closed this as completed Jul 20, 2012
@cwise
Copy link

cwise commented Jul 20, 2012

Thanks for this.

@mraaroncruz
Copy link

I am not getting an exception anymore. Thanks!

@mraaroncruz
Copy link

Void is still broken, but that is probably a different issue...

@radar
Copy link

radar commented Jul 24, 2012

@pferdefleisch Please create a new issue and provide steps to reproduce the issue you're seeing regarding void.

Thanks!

@mraaroncruz
Copy link

@radar Yeah, sorry about that. I will debug it a bit, later today.

@cwise
Copy link

cwise commented Aug 9, 2012

I thought I should leave a note here for anyone that runs into an issue with "Transaction ID is invalid" after upgrading. It used to be that the authorization was pulled from the log_entries associated with the payment. Later, it was updated to pass the response_code field from the payment itself.

The problem occurs if you have older orders that were authorized under the old scheme. The value of response_code will be something like "Success" instead of the auth id. You can fix this by grabbing the authorization from logs. Here's a snippet:

Spree::Order.complete.where("state = 'complete' AND payment_state IN ('balance_due')").each do |order|
  if order.payment && order.payment.response_code = 'Success' && order.payment.log_entries.first
    auth_match = order.payment.log_entries.first.details.match(/authorization\:\s+(\w+)\s/i)
    authorization = auth_match[1] if auth_match
    order.payment.update_attribute(:response_code, authorization) if authorization
  end
end

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.