首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails -Stripe::Bookings#new中的InvalidRequestError必须提供源或客户

Rails -Stripe::Bookings#new中的InvalidRequestError必须提供源或客户
EN

Stack Overflow用户
提问于 2016-09-27 12:58:23
回答 2查看 719关注 0票数 0

我在我的Rails应用程序中得到了上面的错误。我的预订模型里有下面的条形码-

booking.rb

代码语言:javascript
复制
    class Booking < ActiveRecord::Base

    belongs_to :event
    belongs_to :user

    validates :quantity, presence: true, numericality: { greater_than: 0 }
    validates :event, presence: true, numericality: {greater_than_or_equal_to: 0 }

    before_save :set_price_to_zero_if_free

    def set_price_to_zero_if_free
       self.event.price >= 1    unless self.event.is_free
    end

    def reserve
        # Don't process this booking if it isn't valid
        #return unless valid?

        # We can always set this, even for free events because their price will be 0.
        #self.total_amount = booking.quantity * event.price

            # Free events don't need to do anything special
            if event.is_free?
            save!

            # Paid events should charge the customer's card
        else

            begin
                charge = Stripe::Charge.create(
                    amount: total_amount,
                    currency: "gbp",
                    source: 'token', 
                    description: "Booking created for amount #{total_amount}")
                    self.stripe_charge_id = charge.id
                    save!
            rescue Stripe::CardError => e
            errors.add(:base, e.message)
            false
            end
        end 
    end
end

bookings_controller.rb

代码语言:javascript
复制
  class BookingsController < ApplicationController

    before_action :authenticate_user!

    def new
        # booking form
        # I need to find the event that we're making a booking on
        @event = Event.find(params[:event_id])
        # and because the event "has_many :bookings"
        @booking = @event.bookings.new(quantity: params[:quantity])
        # which person is booking the event?
        @booking.user = current_user
        #@booking.quantity = @booking.quantity
        #@total_amount = @booking.quantity.to_f * @event.price.to_f


    end

    def create

        # actually process the booking
        @event = Event.find(params[:event_id])
        @booking = @event.bookings.new(booking_params)
        @booking.user = current_user

            if 
                @booking.reserve
                flash[:success] = "Your place on our event has been booked"
                redirect_to event_path(@event)
            else
                flash[:error] = "Booking unsuccessful"
                render "new"
            end
    end






    private

    def booking_params
        params.require(:booking).permit(:stripe_token, :quantity, :event_id, :stripe_charge_id)
    end



end

booking.new.html.erb

代码语言:javascript
复制
    <div class="col-md-6 col-md-offset-3" id="eventshow">
  <div class="row">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h2>Confirm Your Booking</h2>
        </div>
                  <div class="calculate-total">
                              <p>
                                  Confirm number of spaces you wish to book here:
                                    <input type="number" placeholder="1"  min="1" value="1" class="num-spaces">
                              </p>
                                <p>
                                    Total Amount
                                    £<span class="total" data-unit-cost="<%= @event.price %>">0</span>
                                </p>
                          </div>





                <%= simple_form_for [@event, @booking], id: "new_booking" do |form| %>



                 <span class="payment-errors"></span>

                <div class="form-row">
                    <label>
                      <span>Card Number</span>
                      <input type="text" size="20" data-stripe="number"/>
                    </label>
                </div>

                <div class="form-row">
                  <label>
                  <span>CVC</span>
                  <input type="text" size="4" data-stripe="cvc"/>
                  </label>
                </div>

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

               <%= form.button :submit %>


            </div> 

<% end %>
<% end %>

      </div>
  </div>
</div>  

<script type="text/javascript">
    $('.calculate-total input').on('keyup change', calculateBookingPrice);

function calculateBookingPrice() {
  var unitCost = parseFloat($('.calculate-total .total').data('unit-cost')),
      numSpaces = parseInt($('.calculate-total .num-spaces').val()),
      total = (numSpaces * unitCost).toFixed(2);

  if (isNaN(total)) {
    total = 0;
  }

  $('.calculate-total span.total').text(total);
}

  $(document).ready(calculateBookingPrice)

</script>



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

<script type="text/javascript">
  Stripe.setPublishableKey('<%= STRIPE_PUBLIC_KEY %>');
  var stripeResponseHandler = function(status, response) {
    var $form = $('#new_booking');

    if (response.error) {
    // Show the errors on the form
    $form.find('.payment-errors').text(response.error.message);
    $form.find('input[type=submit]').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="booking[stripe_token]"     />').val(token));
    // and submit
    $form.get(0).submit();
    }
  };

  // jQuery(function($)  { - changed to the line below
  $(document).on("ready page:load", function () {

    $('#new_booking').submit(function(event) {
      var $form = $(this);

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

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

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

当我清楚地在我的条形码中包含源代码时,我不明白为什么我会得到错误。我在上面将它表示为self.stripe_token,但我尝试了stripe_token,但仍然得到了相同的错误。我的理解是,我需要要么提供资源,要么提供客户,而不是两者兼而有之,而且它需要是源而不是客户。

我遗漏了什么?

EN

回答 2

Stack Overflow用户

发布于 2016-09-27 16:46:43

如果您得到“必须提供源或客户”作为错误消息,这意味着代码中的self.stripe_token必须是nil或空字符串。

您需要确保source参数的值是一个有效的令牌ID。令牌应该用结帐Stripe.js创建客户端。创建令牌后,需要将其发送到服务器(通常是POST参数),以便在费用产生请求中使用它。

您还可以在仪表板中检查您的帐户日志,以查看您的集成发送的请求,这在调试问题时非常有用:https://dashboard.stripe.com/test/logs/overview

票数 0
EN

Stack Overflow用户

发布于 2016-09-28 16:03:34

我猜想stripe_token不是booking模型中的一个属性。这就是为什么当您尝试用self.stripe_token检索它的值时,它会给您nil

尝试将令牌从控制器参数传递到模型实例方法:

主计长:

代码语言:javascript
复制
if @booking.reserve(booking_params['stripe_token'])
  # everything is good
else
  # ops
end

模型:

代码语言:javascript
复制
def reserve(stripe_token)
  if event.is_free?
    save!
  else
    begin
      charge = Stripe::Charge.create(
                   amount: total_amount,
                   currency: "gbp",
                   source: stripe_token,
                    ....
       )
       # rest of method
  end

更新:

当前,您的代码有设置total_amount的部分,注释掉了!

通常,您会想要制作如下内容:

代码语言:javascript
复制
total_amount = self.booking.event.price * 100 #not really sure how should calculate this? 
charge = Stripe::Charge.create(
            amount: total_amount,
            currency: "gbp",
            source: 'token', 
            description: "Booking created for amount #{total_amount}"
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39725329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档