2015-01-31 49 views
1

我正在电子商务/市场应用上处理卡支付。用户填写订单,包括送货地址,账单信息等,然后提交。如果填写的表单没有错误,则表单按预期工作,即保存订单并收取卡。Rails 4 - 出现表单错误时处理卡支付

问题:表单发生错误时(例如:zip为空),表单页面会返回错误消息。但是如果信用卡信息是正确的,用户就会被收取费用。只有在没有表单错误的情况下,我才需要卡才能充电。

这是我的订单控制器中的create方法。我想过在respond_to块中移动条带电荷块,但这不起作用,因为只有在付款批准后才能保存订单。

由于这是一个市场,我还有一个付款转账区块,也就是说付款的一部分被转移给物品的卖家。此代码只应在处理付款并保存订单后运行。

def create 
    @order = Order.new(order_params) 

    Stripe.api_key = ENV["STRIPE_API_KEY"] 
    token = params[:stripeToken] 


    begin 
     charge = Stripe::Charge.create(
     :amount => (@listing.price * 100).floor, 
     :currency => "usd", 
     :card => token, 
     :description => "Charge from ABC" 
     ) 

    respond_to do |format| 
     if @order.save 
     format.html { redirect_to thankyou_path(:id => @order.id) } 
     format.json { render action: 'show', status: :created, location: @order } 
     AutoNotifier.orderconf_email(current_user, @order).deliver 
     AutoNotifier.sellerconf_email(current_user, @seller, @order).deliver 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @order.errors, status: :unprocessable_entity } 
     end 
    end #end respond_to 

    if [email protected]? 
     transfer = Stripe::Transfer.create(
      :amount => (((@listing.price * 97.1) - 30) * 0.8).floor, #converting to cents per stripe requirement. 80 percent in cents goes to seller. 
      :currency => "usd", 
      :recipient => @seller.recipient 
     ) 
    end #end transfer 

    rescue Stripe::CardError => e 
     flash[:danger] = e.message 
    end #end rescue 

    end #end begin 

end #end create 
+0

您是否找到解决方案? – Tobias 2015-12-17 14:31:33

+0

是的,我使用了Deep发布的解决方案的变体。回复较晚,抱歉。我不在这里。 – Moosa 2016-01-13 18:07:56

回答

0

你可以做的是将条带电荷移动到模型中的方法。然后只需添加一个条件是这样的:

def save_with_payment 
    if self.valid? 
     charge = Stripe::Charge.create(
    :amount => (@listing.price * 100).floor, 
    :currency => "usd", 
    :card => token, 
    :description => "Charge from ABC" 
    ) 
     self.stripe_customer_token = charge.id 
     save! 
    else 
     logger.error "#{self.errors.inspect}" 
     false 
    end 
    rescue Stripe::InvalidRequestError => e 
    logger.error "Stripe error while creating charge: #{e.message}" 
    errors.add :base, "There was a problem with your credit card." 
    false 
    end 

,并在控制器,你可以做的是:

respond_to do |format| 
     if @order.save_with_payment 
     format.html { redirect_to thankyou_path(:id => @order.id) } 
     format.json { render action: 'show', status: :created, location: @order } 
     AutoNotifier.orderconf_email(current_user, @order).deliver 
     AutoNotifier.sellerconf_email(current_user, @seller, @order).deliver 
     else 
     format.html { render action: 'new' } 
     format.json { render json: @order.errors, status: :unprocessable_entity } 
     end 
    end #end respond_to 

因此,这将检查用户输入的数据是有效的,那么只有将用户收费。希望这可以帮助。

0

我假设您在创建订单之前创建了费用,因为您希望在创建订单之前确保交易有效。

您在这里有几个选项。

  1. 您可以@order.valid?验证为了创建充电前,但将返回false,如果您有条纹充验证。

  2. 您也可以验证充电而不捕获它,因为每this page on the stripe support website,就像这样:

    charge = Stripe::Charge.create(
        :amount => (@listing.price * 100).floor, 
        :currency => "usd", 
        :card => token, 
        :description => "Charge from ABC" 
        :capture => false 
        ) 
    

    通知的:capture => false。然后,一旦您创建订单,您可以致电charge.capture。但是,您仍然希望处理(不太可能)的情况,即charge.capture返回错误或引发异常,并删除订单。

您也可以退还货款,如果@order.save返回假的,但我建议你输入错误至少检查您捕获的收费之前。

0

也许你应该看看交易。如果事务中的某些事件引发异常,则其中的所有内容都将恢复。