我在我的Rails应用程序中得到了上面的错误。我的预订模型里有下面的条形码-
booking.rb
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
endbookings_controller.rb
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
endbooking.new.html.erb
<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,但仍然得到了相同的错误。我的理解是,我需要要么提供资源,要么提供客户,而不是两者兼而有之,而且它需要是源而不是客户。
我遗漏了什么?
发布于 2016-09-27 16:46:43
如果您得到“必须提供源或客户”作为错误消息,这意味着代码中的self.stripe_token必须是nil或空字符串。
您需要确保source参数的值是一个有效的令牌ID。令牌应该用结帐或Stripe.js创建客户端。创建令牌后,需要将其发送到服务器(通常是POST参数),以便在费用产生请求中使用它。
您还可以在仪表板中检查您的帐户日志,以查看您的集成发送的请求,这在调试问题时非常有用:https://dashboard.stripe.com/test/logs/overview。
发布于 2016-09-28 16:03:34
我猜想stripe_token不是booking模型中的一个属性。这就是为什么当您尝试用self.stripe_token检索它的值时,它会给您nil。
尝试将令牌从控制器参数传递到模型实例方法:
主计长:
if @booking.reserve(booking_params['stripe_token'])
# everything is good
else
# ops
end模型:
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的部分,注释掉了!
通常,您会想要制作如下内容:
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}"
)https://stackoverflow.com/questions/39725329
复制相似问题