rails 4 条带付款导致订单项无效错误 [英] rails 4 stripe payment causing line item invalid error

查看:50
本文介绍了rails 4 条带付款导致订单项无效错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与使用 Stripe 付款的其他人一样,我收到错误消息无法向没有活动卡的客户收费".表单没有附加令牌,因为 javascript 在表单中没有匹配的 id,但现在我收到一个 rails 错误并且没有向卡收费,客户已创建,错误指出存在无效行item,当创建客户和充值卡的代码没有运行时,订单创建没有错误.

订单查看

<div class = "Power Me" ><字段集><传说>请输入您的详细信息</legend><%= 渲染表单",对象:@object %></fieldset>

提交的订单

<%= form_for(@order, :html => {:id => 'payment-form'}) do |f|%><% if @order.errors.any?%><div id="error_explanation"><h2><%=pluralize(@order.errors.count, "error") %>禁止保存此订单:</h2><ul><% @order.errors.full_messages.each do |message|%><li><%=消息%></li><%结束%>

<%结束%><div class="field"><%= "订单总数:#{order_total.to_s}" %><%= "订单货币:#{order_currency.to_s}" %>

<div class="field"><%= f.label :name %><br><%= f.text_field :name %>

<div class="field"><%= f.label :Address_line_1 %><br><%= f.text_area :address_line_1 %>

<div class="field"><%= f.label :Address_Line_2 %><br><%= f.text_area :address_line_2 %>

<div class="field"><%= f.label :City %><br><%= f.text_area :address_city %>

<div class="field"><%= f.label :Region %><br><%= f.text_area :address_state %>

<div class="field"><%= f.label :邮政编码 %><br><%= f.text_area :address_zip %>

<div class="field"><%= f.label :Country%><br><%= f.select :address_country, Order::CC_COUNTRIES, prompt: 'Select the country' %>

<div class="field"><%= f.label :email %><br><%= f.text_field :email, :placeholder =>"you@example.com" %>

<div class="field"><%= f.label :Pay​​ment_Type %><br><%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method' %>

<div class="form-row"><label>卡号</label><input type="text" size="20" autocomplete="off" data-stripe="number" id="number" class="credit-number", placeholder = "**** **** **** ****" 模式="[\d ]*"/>

<div class="form-row"><label>安全码/CVC</label><input type="text" size="4" autocomplete="off" data-stripe="cvc" id="cvc" class="credit-scurity" placeholder="***" pattern="\d*"/>

<div class="form-row"><label>过期时间 (MM/YYYY)</label><input type="text" size="2" data-stripe="exp-month" id="exp-month" class="card-expiry-month" placeholder="MM" pattern="\d*"/><跨度>/</span><input type="text" size="4" data-stripe="exp-year" id="exp-year" class="card-expiry-year" placeholder="YYYY" pattern="\d*"/>

<div class="actions"><%= f.submit 'Pay', :class =>"stripe-button" %>

<%结束%>

订单模型

class Order 

订单控制器

class OrdersController <应用控制器包括当前购物车before_action :set_cart, only: [:new, :create]before_action :set_order, only: [:show, :edit, :update, :destroy]# 获取/订单# 获取/orders.json定义索引@orders = Order.all结尾# 获取/订单/1# 获取/orders/1.json高清秀结尾# 获取/订单/新定义新如果@cart.line_items.empty?redirect_to store_url,注意:您的购物车是空的"返回结尾@order = Order.new结尾# 获取/订单/1/编辑定义编辑结尾# 发布/订单# POST/orders.json定义创建@order = Order.new(order_params)@order.add_line_items_from_cart(@cart)response_to do |格式|如果@order.saveCart.destroy(会话[:cart_id])session[:cart_id] = nilformat.html { redirect_to @order,注意:'订单已成功创建.'}format.json { 渲染动作:'show',状态::已创建,位置:@order }别的format.html { 渲染动作:'新' }format.json { 渲染 json: @order.errors, 状态: :unprocessable_entity }结尾结尾Stripe.api_key = "sk_test_BsdqHq0SQuPqHIsm46lcpX4v"@amount = order_total.to_i * 100令牌 = params[:stripeToken]=开始开始customer = Stripe::Customer.create(:email =>order_params[:email])充电 = 条纹::充电.创建(:客户 =>客户ID,:金额=>@amount, # 以美分为单位的金额,再次:货币=>订单货币,:卡=>令牌,:描述 =>order_params[:email])重定向到 root_path救援 Stripe::CardError =>电子@错误=e结尾=结束结尾# 补丁/放置/订单/1# PATCH/PUT/orders/1.json定义更新response_to do |格式|如果@order.update(order_params)format.html { redirect_to @order,注意:'订单已成功更新.'}format.json { 头:no_content }别的format.html { 渲染动作:'编辑' }format.json { 渲染 json: @order.errors, 状态: :unprocessable_entity }结尾结尾结尾# 删除/orders/1# 删除/orders/1.json销毁@order.destroyresponse_to do |格式|format.html { redirect_to orders_url }format.json { 头:no_content }结尾结尾私人的# 使用回调在动作之间共享公共设置或约束.def set_order@order = Order.find(params[:id])结尾# 永远不要相信来自可怕互联网的参数,只允许白名单通过.def order_paramsparams.require(:order).permit(:name, :email, :pay_type, :address_line_1, :address_line_2, :address_city, :address_state, :address_zip, :address_country)结尾结尾

我的应用助手

module ApplicationHelperdef order_totaltotal = LineItem.joins(:product).select("sum(line_items.quantity * products.price) as total").where("cart_id = ?", session[:cart_id]).first.total结尾def order_currency货币 = LineItem.joins(:product).joins(:currency).select("currencies.name as iso_name").where("cart_id = ?", session[:cart_id]).first.iso_name结尾# 按页返回完整标题.def full_title(page_title)base_title = "Ruby on Rails 教程示例应用程序"如果 page_title.empty?base_title别的#{base_title} | #{page_title}"结尾结尾def bootstrap_class_for flash_type{成功:警报成功",错误:警报危险",警报:警报警告",通知:警报信息"}[flash_type] ||flash_type.to_s结尾def flash_messages(opts = {})flash.each do |msg_type, message|concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} 淡入") do连接消息结尾)结尾零结尾# 过滤器前def signed_in_user除非已登录?商店地址redirect_to signin_url,注意:请登录."结尾结尾定义正确_用户@user = User.find(params[:id])redirect_to(root_url) 除非 current_user?(@user)结尾定义 admin_userredirect_to(root_url) 除非 current_user.admin?结尾结尾

订单.js

$('#payment-form').submit(function(event) {var form = $(this);form.find('button').prop('disabled', true);Stripe.createToken(form, stripeResponseHandler);返回假;});

解决方案

下面的工作订单表,您不能将字段传递给 Stripe 并在 rails 表单中使用它们以保存在数据库中,其要么或(前面的示例试图保存db 中的地址字段,并将它们作为事务验证的一部分传递给条带.

<%= form_for(@order, :html => {:id => 'payment-form'}) do |f|%><% if @order.errors.any?%><div id="error_explanation"><h2><%=pluralize(@order.errors.count, "error") %>禁止保存此订单:</h2><ul><% @order.errors.full_messages.each do |message|%><li><%=消息%></li><%结束%>

<%结束%><div class="field"><%= "订单总数:#{order_total.to_s}" %><%= "订单货币:#{order_currency.to_s}" %>

<div class="form-row"><label>全名</label><input type="text" size="20" autocomplete="off" data-stripe="name"/>

<div class="field"><%= f.label :email %><br><%= f.text_field :email, :placeholder =>"you@example.com" %>

<div class="field"><%= f.label :Pay​​ment_Type %><br><%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method', :selected =>信用卡"%>

<div class="form-row"><label>地址行 1</label><input type="text" size="20" autocomplete="off" data-stripe="address_line1"/>

<div class="form-row"><label>地址行 2</label><input type="text" size="20" autocomplete="off"/>

<div class="form-row"><label>地址城市</label><input type="text" size="20" autocomplete="off"/>

<div class="form-row"><label>地址状态</label><input type="text" size="20" autocomplete="off"/>

<div class="form-row"><label>邮政编码</label><input type="text" size="20" autocomplete="off" data-stripe="address_zip"/>

<div class="form-row"><label>国家</label><input type="text" size="20" autocomplete="off" data-stripe="address_country"/>

<div class="form-row"><label>卡号</label><input type="text" size="20" autocomplete="off" data-stripe="number" placeholder = "**** **** **** ****" pattern="[\d ]*"/>

<div class="form-row"><label>安全码/CVC</label><input type="text" size="4" autocomplete="off" data-stripe="cvc" placeholder="***" pattern="\d*"/>

<div class="form-row"><label>过期时间 (MM/YYYY)</label><input type="text" size="2" data-stripe="exp-month" placeholder="MM" pattern="\d*"/><跨度>/</span><input type="text" size="4" data-stripe="exp-year" placeholder="YYYY" pattern="\d*"/>

<div class="actions"><%= f.submit 'Pay', :class =>按钮"%>

<%结束%>

表单需要在下面的javascript中引用的id

var stripeResponseHandler = function(status, response) {var $form = $('#payment-form');如果(响应.错误){//在表单上显示错误$form.find('.payment-errors').text(response.error.message);$form.find('button').prop('disabled', false);} 别的 {//token 包含 id、last4 和卡片类型var token = response.id;//将令牌插入到表单中,以便将其提交给服务器$form.append($('<input type="hidden" name="stripeToken"/>').val(token));//并重新提交$form.get(0).submit();}};jQuery(函数($){$('#payment-form').submit(function(e) {var $form = $(this);//禁用提交按钮以防止重复点击$form.find('button').prop('disabled', true);Stripe.card.createToken($form, stripeResponseHandler);//防止表单使用默认操作提交返回假;});});

订单模型,已删除字段

class Order 

应用标题

<头><title><%= full_title(yield(:title)) %></title><%= stylesheet_link_tag "application", media: "all",数据涡轮链接轨道"=>真%><%= javascript_include_tag "application", "data-turbolinks-track" =>真%><script type="text/javascript" src="https://js.stripe.com/v2/"></script><script type="text/javascript">$(函数(){Stripe.setPublishableKey('<%= Rails.configuration.stripe[:publishable_key] %>');});<%= csrf_meta_tags %><%=渲染'布局/垫片'%><身体>

订单控制器

class OrdersController <应用控制器包括当前购物车before_action :set_cart, only: [:new, :create]before_action :set_order, only: [:show,:edit, :update, :destroy]# before_action :admin_user, only: [:destroy, :show]# 获取/订单# 获取/orders.json定义索引@orders = Order.all结尾# 获取/订单/1# 获取/orders/1.json高清秀结尾# 获取/订单/新定义新如果@cart.line_items.empty?redirect_to store_url,注意:您的购物车是空的"返回结尾@order = Order.new结尾# 获取/订单/1/编辑定义编辑结尾# 发布/订单# POST/orders.json定义创建开始@order = Order.new(order_params)@order.add_line_items_from_cart(@cart)Stripe.api_key = "sk_test_xxxxxxxxxxxxxxx"@amount = order_total.to_i * 100令牌 = params[:stripeToken]# 创建一个客户customer = Stripe::Customer.create(:描述 =>order_params[:email],:卡=>令牌,)充电 = 条纹::充电.创建(:客户 =>客户ID,:金额=>@amount, # 以美分为单位的金额,再次:货币=>订单货币,# :card =>令牌,:描述 =>order_params[:email])response_to do |格式|如果@order.save把现在储蓄"Cart.destroy(会话[:cart_id])session[:cart_id] = nilformat.html { redirect_to @order,注意:'订单已成功创建.'}format.json { 渲染动作:'show',状态::已创建,位置:@order }别的format.html { 渲染动作:'新' }format.json { 渲染 json: @order.errors, 状态: :unprocessable_entity }结尾结尾救援 Stripe::CardError =>电子flash[:error] = e.message重定向到 root_path结尾结尾# 补丁/放置/订单/1# PATCH/PUT/orders/1.json定义更新response_to do |格式|如果@order.update(order_params)format.html { redirect_to @order,注意:'订单已成功更新.'}format.json { 头:no_content }别的format.html { 渲染动作:'编辑' }format.json { 渲染 json: @order.errors, 状态: :unprocessable_entity }结尾结尾结尾# 删除/orders/1# 删除/orders/1.json销毁@order.destroyresponse_to do |格式|format.html { redirect_to orders_url }format.json { 头:no_content }结尾结尾私人的# 使用回调在动作之间共享公共设置或约束.def set_order@order = Order.find(params[:id])结尾# 永远不要相信来自可怕互联网的参数,只允许白名单通过.def order_paramsparams.require(:order).permit(:email, :pay_type)结尾结尾

Like others working with Stripe payments, I was getting an error 'Cannot charge a customer that has no active card'. The form was not appending the token because the javascript did not have a matching id in the form, but now I am getting an rails error and the card is not being charged, the customer is created, the error states that there is an invalid line item, when the code to create the customer and charge the card is not run the order is created without error.

Order View

<script type="text/javascript" src="https://js.stripe.com/v2/">

$(function(){

  Stripe.setPublishableKey('<%= Rails.configuration.stripe[:PUBLISHABLE_KEY] %>');

});

</script>

<div class = "Power Me" >

  <fieldset>

    <legend> Please enter your details </legend>

    <%= render 'form', object: @object %>

  </fieldset>

</div>

Rendered Order Form

<%= form_for(@order, :html => {:id => 'payment-form'}) do |f| %>

  <% if @order.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@order.errors.count, "error") %> prohibited this order from being saved:</h2>

      <ul>
      <% @order.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">

    <%= "Order Total: #{order_total.to_s}" %>
    <%= "Order Currency: #{order_currency.to_s}" %>
  </div>

  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :Address_line_1 %><br>
    <%= f.text_area :address_line_1 %>
  </div>
  <div class="field">
    <%= f.label :Address_Line_2 %><br>
    <%= f.text_area :address_line_2 %>
  </div>
  <div class="field">
    <%= f.label :City %><br>
    <%= f.text_area :address_city %>
  </div>
  <div class="field">
    <%= f.label :Region %><br>
    <%= f.text_area :address_state %>
  </div>
  <div class="field">
    <%= f.label :Postcode %><br>
    <%= f.text_area :address_zip %>
  </div>
  <div class="field">
    <%= f.label :Country %><br>
    <%= f.select :address_country, Order::CC_COUNTRIES, prompt: 'Select the country' %>
  </div>
  <div class="field">
    <%= f.label :email %><br>
    <%= f.text_field :email, :placeholder => "you@example.com" %>
  </div>
  <div class="field">
    <%= f.label :Payment_Type %><br>
    <%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method' %>
  </div>
  <div class="form-row">
        <label>Card Number</label>
        <input type="text" size="20" autocomplete="off" data-stripe="number" id="number" class="credit-number", placeholder = "**** **** **** ****" pattern="[\d ]*" />
    </div>

    <div class="form-row">
        <label>Security Code/CVC</label>
        <input type="text" size="4" autocomplete="off" data-stripe="cvc" id="cvc" class="credit-scurity" placeholder="***" pattern="\d*" />
    </div>

    <div class="form-row">
        <label>Expiration (MM/YYYY)</label>
        <input type="text" size="2" data-stripe="exp-month" id="exp-month" class="card-expiry-month" placeholder="MM" pattern="\d*" />
        <span> / </span>
        <input type="text" size="4" data-stripe="exp-year" id="exp-year" class="card-expiry-year" placeholder="YYYY" pattern="\d*" />
    </div>

  <div class="actions">
    <%= f.submit 'Pay', :class =>"stripe-button" %>
  </div>
<% end %>

orders model

class Order < ActiveRecord::Base

#  attr_accessor :stripeToken

  PAYMENT_TYPES = ["credit card"]

  CC_COUNTRIES = ["United Kingdom", "France", "Italy"]

  validates :name, :address_line_1, :address_zip, :email, presence: true

#  validates :pay_type, inclusion: PAYMENT_TYPES

  has_many :line_items, dependent: :destroy

  def add_line_items_from_cart(cart)

    cart.line_items.each do |item|

      item.cart_id = nil

      line_items << item

    end

  end
end

Orders Controller

class OrdersController < ApplicationController

  include CurrentCart

  before_action :set_cart, only: [:new, :create]

  before_action :set_order, only: [:show, :edit, :update, :destroy]

  # GET /orders
  # GET /orders.json
  def index
    @orders = Order.all
  end

  # GET /orders/1
  # GET /orders/1.json
  def show
  end

  # GET /orders/new
  def new

    if @cart.line_items.empty?

      redirect_to store_url, notice: "Your cart is empty"

      return

    end

    @order = Order.new

  end

  # GET /orders/1/edit
  def edit
  end

  # POST /orders
  # POST /orders.json
  def create

    @order = Order.new(order_params)

    @order.add_line_items_from_cart(@cart)

    respond_to do |format|
      if @order.save

        Cart.destroy(session[:cart_id])

        session[:cart_id] = nil

        format.html { redirect_to @order, notice: 'Order was successfully created.' }
        format.json { render action: 'show', status: :created, location: @order }
      else
        format.html { render action: 'new' }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end

    Stripe.api_key = "sk_test_BsdqHq0SQuPqHIsm46lcpX4v"

    @amount = order_total.to_i * 100

    token = params[:stripeToken]
=begin
    begin

      customer = Stripe::Customer.create(

        :email => order_params[:email]

      )

      charge = Stripe::Charge.create(

        :customer    => customer.id,
        :amount => @amount, # amount in cents, again
        :currency => order_currency,
        :card => token,
        :description => order_params[:email]
      )

      redirect_to root_path

    rescue Stripe::CardError => e

      @error = e

    end
=end
  end

  # PATCH/PUT /orders/1
  # PATCH/PUT /orders/1.json
  def update
    respond_to do |format|
      if @order.update(order_params)
        format.html { redirect_to @order, notice: 'Order was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /orders/1
  # DELETE /orders/1.json
  def destroy
    @order.destroy
    respond_to do |format|
      format.html { redirect_to orders_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_order
      @order = Order.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def order_params
      params.require(:order).permit(:name, :email, :pay_type, :address_line_1, :address_line_2, :address_city, :address_state, :address_zip, :address_country)
    end
end

My Application Helper

module ApplicationHelper

      def order_total

        total = LineItem.joins(:product).select("sum(line_items.quantity * products.price) as total").where("cart_id = ?", session[:cart_id]).first.total

      end

      def order_currency

        currency = LineItem.joins(:product).joins(:currency).select("currencies.name as iso_name").where("cart_id = ?", session[:cart_id]).first.iso_name

      end


      # Returns the full title on a per-page basis.
      def full_title(page_title)
        base_title = "Ruby on Rails Tutorial Sample App"
        if page_title.empty?
          base_title
        else
          "#{base_title} | #{page_title}"
        end
      end

      def bootstrap_class_for flash_type

        { success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }[flash_type] || flash_type.to_s

      end

      def flash_messages(opts = {})

        flash.each do |msg_type, message|

          concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do

            concat message
         end)

        end

          nil

      end

      # before filters

      def signed_in_user

        unless signed_in?

          store_location

          redirect_to signin_url, notice: "Please sign in."

        end

      end

      def correct_user

        @user = User.find(params[:id])

        redirect_to(root_url) unless current_user?(@user)

      end

      def admin_user

        redirect_to(root_url) unless current_user.admin?

      end

end

Orders.js

$('#payment-form').submit(function(event) {

  var form = $(this);

  form.find('button').prop('disabled', true);

  Stripe.createToken(form, stripeResponseHandler);

  return false;

});

解决方案

Working Order Form below, you cannot pass fields to Stripe and use them in the rails form to save in the db, its either or (previous example attempted to save address fields in the db and pass them to stripe as part of the transaction validation.

<%= form_for(@order, :html => {:id => 'payment-form'}) do |f| %>

  <% if @order.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@order.errors.count, "error") %> prohibited this order from being saved:</h2>

      <ul>
      <% @order.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">

    <%= "Order Total: #{order_total.to_s}" %>
    <%= "Order Currency: #{order_currency.to_s}" %>

  </div>

  <div class="form-row">
        <label>Full Name</label>
        <input type="text" size="20" autocomplete="off" data-stripe="name" />
  </div>

  <div class="field">
    <%= f.label :email %><br>
    <%= f.text_field :email, :placeholder => "you@example.com" %>
  </div>
  <div class="field">
    <%= f.label :Payment_Type %><br>
    <%= f.select :pay_type, Order::PAYMENT_TYPES, prompt: 'Select a payment method', :selected => "credit card" %>
  </div>

  <div class="form-row">
        <label>Address Line 1</label>
        <input type="text" size="20" autocomplete="off" data-stripe="address_line1" />
    </div>

  <div class="form-row">
        <label>Address Line 2</label>
        <input type="text" size="20" autocomplete="off" />
    </div>

  <div class="form-row">
        <label>Address City</label>
        <input type="text" size="20" autocomplete="off" />
    </div>
  <div class="form-row">
        <label>Address State</label>
        <input type="text" size="20" autocomplete="off" />
    </div>


  <div class="form-row">
        <label>Zip/Postcode</label>
        <input type="text" size="20" autocomplete="off" data-stripe="address_zip" />
    </div>



  <div class="form-row">
        <label>Country</label>
        <input type="text" size="20" autocomplete="off" data-stripe="address_country" />
    </div>
  <div class="form-row">
        <label>Card Number</label>
        <input type="text" size="20" autocomplete="off" data-stripe="number" placeholder = "**** **** **** ****" pattern="[\d ]*" />
    </div>

    <div class="form-row">
        <label>Security Code/CVC</label>
        <input type="text" size="4" autocomplete="off" data-stripe="cvc" placeholder="***" pattern="\d*" />
    </div>

    <div class="form-row">
        <label>Expiration (MM/YYYY)</label>
        <input type="text" size="2" data-stripe="exp-month" placeholder="MM" pattern="\d*" />
        <span> / </span>
        <input type="text" size="4" data-stripe="exp-year" placeholder="YYYY" pattern="\d*" />
    </div>

  <div class="actions">
    <%= f.submit 'Pay', :class => "button" %>
  </div>
<% end %>

The form required the id referenced inthe javascript below

var stripeResponseHandler = function(status, response) {
  var $form = $('#payment-form');

  if (response.error) {
    // Show the errors on the form
    $form.find('.payment-errors').text(response.error.message);
    $form.find('button').prop('disabled', false);
  } else {
    // token contains id, last4, and card type
    var token = response.id;
    // Insert the token into the form so it gets submitted to the server
    $form.append($('<input type="hidden" name="stripeToken" />').val(token));
    // and re-submit
    $form.get(0).submit();
  }
};


jQuery(function($) {

  $('#payment-form').submit(function(e) {
  var $form = $(this);

  // Disable the submit button to prevent repeated clicks
  $form.find('button').prop('disabled', true);

  Stripe.card.createToken($form, stripeResponseHandler);

  // Prevent the form from submitting with the default action
  return false;
  });
});

Order Model, fields removed

class Order < ActiveRecord::Base

  PAYMENT_TYPES = ["credit card"]

  CC_COUNTRIES = ["United Kingdom", "France", "Italy"]

  validates :email, presence: true

  validates :pay_type, inclusion: PAYMENT_TYPES

  has_many :line_items, dependent: :destroy

  def add_line_items_from_cart(cart)

    cart.line_items.each do |item|

      item.cart_id = nil

      line_items << item

    end

  end
end

Application header

<!DOCTYPE html>
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= stylesheet_link_tag "application", media: "all",
                                           "data-turbolinks-track" => true %>
    <%= javascript_include_tag "application", "data-turbolinks-track" => true %>
    <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
    <script type="text/javascript">

      $(function(){

        Stripe.setPublishableKey('<%= Rails.configuration.stripe[:publishable_key] %>');

      });

    </script>
    <%= csrf_meta_tags %>
    <%= render 'layouts/shim' %>
  </head>
  <body>

Order Controller

class OrdersController < ApplicationController

  include CurrentCart

  before_action :set_cart, only: [:new, :create]

  before_action :set_order, only: [:show,:edit, :update, :destroy]

#  before_action :admin_user, only: [:destroy, :show]


  # GET /orders
  # GET /orders.json
  def index
    @orders = Order.all
  end

  # GET /orders/1
  # GET /orders/1.json
  def show
  end

  # GET /orders/new
  def new

    if @cart.line_items.empty?

      redirect_to store_url, notice: "Your cart is empty"

      return

    end

    @order = Order.new

  end

  # GET /orders/1/edit
  def edit
  end

  # POST /orders
  # POST /orders.json
  def create

    begin

      @order = Order.new(order_params)

      @order.add_line_items_from_cart(@cart)

      Stripe.api_key = "sk_test_xxxxxxxxxxxxxxx"

      @amount = order_total.to_i * 100

      token = params[:stripeToken]

      # Create a Customer
      customer = Stripe::Customer.create(

        :description => order_params[:email], 
        :card => token, 

      )


      charge = Stripe::Charge.create(

        :customer    => customer.id,
        :amount => @amount, # amount in cents, again
        :currency => order_currency,
       # :card => token,
        :description => order_params[:email]
      )

      respond_to do |format|

        if @order.save

          puts "saving now"

          Cart.destroy(session[:cart_id])

          session[:cart_id] = nil

          format.html { redirect_to @order, notice: 'Order was successfully created.' }
          format.json { render action: 'show', status: :created, location: @order }
        else
          format.html { render action: 'new' }
          format.json { render json: @order.errors, status: :unprocessable_entity }
        end
      end

      rescue Stripe::CardError => e

      flash[:error] = e.message
      redirect_to root_path
    end
  end

  # PATCH/PUT /orders/1
  # PATCH/PUT /orders/1.json
  def update
    respond_to do |format|
      if @order.update(order_params)
        format.html { redirect_to @order, notice: 'Order was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /orders/1
  # DELETE /orders/1.json
  def destroy
    @order.destroy
    respond_to do |format|
      format.html { redirect_to orders_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_order

      @order = Order.find(params[:id])

    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def order_params

      params.require(:order).permit(:email, :pay_type)

    end
end

这篇关于rails 4 条带付款导致订单项无效错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆