简体   繁体   中英

Rails Stripe Gem - page needs to be refreshed before payment will process

I'm currently building an Events site using rails. I'm using the Stripe gem to process payments. Everything seems to be working fine other than whenever I want to make a payment (in test/development mode at present) I have to refresh the page and re-enter payment details before the payment will process. There's no error code coming up but it happens every time.

What could be causing this? Here's the relevant code -

bookings_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
    # 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
    #@total_amount = @booking.quantity.to_f * @event.price.to_f

    Booking.transaction do
        @booking.save!
        @event.reload
        if @event.bookings.count > @event.number_of_spaces
            flash[:warning] = "Sorry, this event is fully booked."
            raise ActiveRecord::Rollback, "event is fully booked"
        end 
    end

    if @booking.save

        # CHARGE THE USER WHO'S BOOKED
        # #{} == puts a variable into a string
        Stripe::Charge.create(amount: @event.price_pennies, currency: "gbp",
            card: @booking.stripe_token, description: "Booking number #{@booking.id}")

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

    if @event.is_free?

        @booking.save!
        flash[:success] = "Your place on our event has been booked"
        redirect_to event_path(@event)
    end
end


#def total_amount
    #@total_amount = @booking.quantity * @event.price
#end

private

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



end

new.html.erb (bookings)

    <% if @event.is_free? %>
<div class="col-md-6 col-md-offset-3" id="eventshow">
  <div class="row">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h2>Your Booking Confirmation</h2>
        </div>
                <div class="panel-body">

                        <h1>Hi there</h1>

                        <p>You have placed a booking on <%= @event.title %></p>

                        <p>Your order number is <%= @booking.id %></p>

                        <p>We hope you have a wonderful time. Enjoy!</p>

                        <p>Love from Mama Knows Best</p>
                </div>        
                  <div class="panel-footer">
                    <%= link_to "Home", root_path %>
                  </div>
    </div>
  </div>
</div>                      

                <% else %>

<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="panel-body">    

                <p>Total Amount<%= @event.price %></p>
                <%= 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" src="https://js.stripe.com/v2/"></script>

<script type="text/javascript">
  // This identifies your website in the createToken call below
  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('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="booking[stripe_token]" />').val(token));
    // and re-submit
    $form.get(0).submit();
  }
};

jQuery(function($) {
  $('#new_booking').submit(function(e) {
    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>

Here's the output from the terminal when I click on 'create booking' the first time before I refresh -

Started GET "/events/23/bookings/new" for ::1 at 2016-07-28 16:09:14 +0100
Processing by BookingsController#new as HTML
  Parameters: {"event_id"=>"23"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 2]]
  Event Load (0.1ms)  SELECT  "events".* FROM "events" WHERE "events"."id" = ? LIMIT 1  [["id", 23]]
  Rendered bookings/new.html.erb within layouts/application (4.3ms)
Completed 200 OK in 132ms (Views: 128.6ms | ActiveRecord: 0.2ms)

I'm sure it's a simple fix but can't figure it out. Any assistance appreciated.

I think in this part:

@booking.save!
@event.reload

You use reload but actually you are not creating the event in that moment, so I think you don't need to load the event in that way. You are booking the event. Try to removing the reload .

Can you copy and paste the output of the terminal when you try to make the payment at the first time (without refreshing the page)

Some references: http://apidock.com/rails/ActiveRecord/Persistence/reload

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM