0
votes

I have a controller action in rails that is supposed to check if the current braintree status of a transaction is either "submitted_for_settlement" or "authorized" and then void the transaction but if the status is "settled" then refund the transaction. Somehow the controller is voiding all transactions and not working like I want it to. Here is a sample of my code:

@transaction = Braintree::Transaction.find(@id)
if @transaction.status == "authorized" || "submitted_for_settlement" 
  @result = Braintree::Transaction.void(@id)       
elsif @transaction.status == "settled"
   @result = Braintree::Transaction.refund(@id)            
end  


if @result.success?  
@order.update(status: "voided")
 redirect_to orders_path, notice: "transaction successfully voided  "
elsif @result.transaction

 redirect_to orders_path, alert: "transaction could not be cancelled code: #{@result.transaction.processor_response_code} text: #{@result.transaction.processor_response_text}"

else
      errors = @result.errors.map { |error| "Error: #{error.code}: #{error.message}" }
      flash[:error] = errors
      redirect_to orders


end

I am getting an error on transactions that are settled that says" Transactions can only be voided if they are authorized or submitted_for_settlement" but all transactions that are authorized and submitted for settlement are firing correctly.

What is even more troubling is the controller will void the status in the database even when I get the error and the braintree settled transactions remain unchanged.

why am i getting this error?

1

1 Answers

1
votes

Change the line

if @transaction.status == "authorized" || "submitted_for_settlement"

to

@transaction.status == "authorized" || @transaction.status == "submitted_for_settlement"

Because == has higher priority than ||, @transaction.status == "authorized" || "submitted_for_settlement" is equivalent to (@transaction.status == "authorized") || "submitted_for_settlement". So if the status is "authorized", this expression returns true, otherwise it returns the string "submitted_for_settlement", which is also considered truthy in Ruby.

I'd suggest to define some methods to the Braintree::Transaction:

class Braintree::Transaction
  %w(authorized submitted_for_settlement settled).each do |status|
    define_method("#{status}?") do
      self.status == status
    end
  end
end

Then in your controller

if @transaction.authorized? || @transaction.submitted_for_settlement?
  # ...
elsif @transaction.settled?
  # ...
end