Search code examples
rubyruby-on-rails-4stripe-paymentsactivemerchant

How to display payment gateway response messages in view - Rails 4, Active Merchant


I'm using Active Merchant with Stripe as the payment gateway. Everything works fine except that i don't know how to go about getting the gateway response error messages from Stripe (when a card is declined, invalid etc) to display on the checkout page to the user. I can get a StandardError to be raised that redirects to an error page with the response message but that's it.

ORDER MODEL

class Order < ActiveRecord::Base

has_many :order_products
has_many :products, through: :order_products

attr_accessor :card_number, :security_code, :card_expires_on

validate :validate_card, :on => :create

    def validate_card
    unless credit_card.valid? 
      credit_card.errors.full_messages.each do |message|
       errors[:base] << message

      end

   end
end

def purchase(basket)

    response = GATEWAY.purchase(Product.total_basket_price(basket)*100, credit_card, purchase_options)
        unless response.success? 
         raise StandardError, response.message



    end
end



def credit_card

    @credit_card ||= ActiveMerchant::Billing::CreditCard.new(
        :number                 => card_number,
        :first_name             => first_name,
        :last_name              => last_name,
        :verification_value     => security_code,
        :month                  => card_expires_on.month,
        :year                   => card_expires_on.year
        )
end

def purchase_options 
{
    :billing_address => {
        :address1 => address_1,
        :address2 => address_2,
        :city     => city,
        :country  => country_code,
        :zip      => postal_code 
        }
}

end


end

ORDERS CONTROLLER

class OrdersController < ApplicationController

def create



    @order = Order.new(order_params)

    # @product = basket.find(params[:product_id])


    basket.each do |item_id|
        @order.order_products.build(product: Product.find(item_id))
    end

    if @order.save
        if @order.purchase(basket)

            render "show"
        else
            render "failure"
        end
    else
        render "new"


    end
end

Can anyone lend a hand, please??

Many Thanks


Solution

  • After a lot of fiddling and help, the working solution was to search for an error key within the response params hash and if an error was present add the message to the object errors. Not particularly elegant but it now does what i want.

    ORDER MODEL

    def purchase(basket)
    
        response = GATEWAY.purchase(Product.total_basket_price(basket)*100, credit_card, purchase_options)
    
            if response.params.key?('error')
    
                self.errors.add :base, response.message
    
                false
    
            else 
                true
    
            end 
    
    end
    

    ORDERS CONTROLLER

    Also switched the order of the if statements in the controller so that def purchase(basket) runs first before the order is saved, allowing the error message(s) from the response to be caught and displayed.

    if @order.purchase(basket)
            if @order.save
    
                render "show"   
            else 
    
                render "new"
    
    
            end
        else
            render "new"
    
    
        end
    

    VIEW

    <%= if @order.errors.any?
               @order.errors[:base].to_sentence
    
    end%>