如何在视图中显示支付网关响应消息 - Rails 4,Active Merchant

Posted

技术标签:

【中文标题】如何在视图中显示支付网关响应消息 - Rails 4,Active Merchant【英文标题】:How to display payment gateway response messages in view - Rails 4, Active Merchant 【发布时间】:2014-06-27 07:49:18 【问题描述】:

我正在使用带有 Stripe 的 Active Merchant 作为支付网关。一切正常,除了我不知道如何从 Stripe 获取网关响应错误消息(当卡被拒绝、无效等)以在结帐页面上显示给用户。我可以引发一个 StandardError,它会重定向到带有响应消息的错误页面,仅此而已。

订单模型

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

订单控制器

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

有人可以帮忙吗?

非常感谢

【问题讨论】:

【参考方案1】:

简单易懂!

这是一个简单的控制流问题。在 Ruby 中,与大多数语言一样,异常会中断正常的程序流程。正如您现在编写的代码一样,#purchase 在失败时会引发异常。

这很好,是一个完全有效的设计决策。但是与#purchase交互的代码是这样的:

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

该代码没有异常处理,因此 Rails 将捕获任何异常,程序流程将停止,您将获得详细的错误页面(在开发模式下)或通用 500 错误页面(在生产模式下) .

由于您自称是 Ruby 和 Rails 的新手,因此稍微替换一下代码可能会更清楚:

# If #purchase is successful, it evaluates to true.
if true
  render "show"       # 'show' view is rendered as expected. Flow stops.
else
  render "failure"
end

# If #purchase fails, it raises an exception.
if raise StandardError, response.message
  # ^^^ Exception is raised, flow stops here.
  render "show"       # This code is never reached.
else                  # This code is never reached.
  render "failure"    # This code is never reached.
end

不过,正如我在开头所暗示的那样,一旦您知道问题所在,这很容易解决。您可以使用rescue 简单地处理异常。如果你当前有一个 if/else 块,你可以交换一个 if 块和一个救援块:

if @order.purchase(basket)
  render 'show'
end
rescue => e
  render 'failure'

根据您的需要,这里还有改进的余地——例如,因为你正在提高和拯救StandardError,你不能轻易区分网络故障和被拒绝的卡——但它会让你再次行动.

【讨论】:

谢谢@colinm,这有点帮助。我试过谷歌搜索rescue 以及如何使用它,但没有找到很多。【参考方案2】:

经过大量的摆弄和帮助,有效的解决方案是在响应参数哈希中搜索 error 键,如果出现错误,则将消息添加到对象错误中。不是特别优雅,但它现在可以满足我的需求。

订单型号

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

订单控制器

还切换了控制器中if 语句的顺序,以便def purchase(basket) 在保存顺序之前首先运行,从而可以捕获并显示响应中的错误消息。

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

            render "show"   
        else 

            render "new"


        end
    else
        render "new"


    end

查看

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

end%>

【讨论】:

以上是关于如何在视图中显示支付网关响应消息 - Rails 4,Active Merchant的主要内容,如果未能解决你的问题,请参考以下文章

CCAvenue 支付网关与 rails 应用程序的集成

用于安全支付的最佳支付网关和 Rails gem? [关闭]

在 Spree 支持的 Ruby on Rails 电子商务应用程序中集成印度支付网关 (CCAvenue)

在 Rails 中,如何使用视图呈现 JSON?

当没有找到与 Rails 的 JQuery 自动完成匹配时如何显示响应

支付成功后渲染视图