2

我在提交新的客户表单以进行条带化时遇到问题。如果我从上到下填写表格,电子邮件,信用卡信息,然后点击提交,表格将失败(“您的信用卡有问题”)。在条纹结束时,发送电子邮件但卡信息为空白。

但是,如果我先填写信用卡信息,点击提交,然后填写电子邮件,一切正常。在应用程序上进行了新订阅,并在条带中创建了新客户。

我确定我做错了什么。这是代码:

新的.html.erb

<h1>Signing up for <%= @subscription.plan.name %></h1>
 <strong><%= @subscription.plan.price %></strong> per month!</p>

 <%= form_for @subscription do |f| %>
   <% if @subscription.errors.any? %>
     <div class="error_messages">
       <h2><%= pluralize(@subscription.errors.count, "error") %> prohibited this subscription from being saved:</h2>
       <ul>
       <% @subscription.errors.full_messages.each do |msg| %>
         <li><%= msg %></li>
       <% end %>
       </ul>
     </div>
   <% end %>

   <%= f.hidden_field :plan_id %>

   <%= f.hidden_field :stripe_card_token %>

   <div class="field">
     <%= f.label :email %>
     <%= f.text_field :email, "data-stripe" => "email" %>
   </div>

   <% if @subscription.stripe_card_token.present? %>
     <p>Credit card has been provided.</p>
   <% else %>
     <div class="field">
       <%= label_tag :card_number, "Credit Card Number" %>
       <%= text_field_tag :card_number, nil, name: nil, "data-stripe" => "number" %>
     </div>
     <div class="field">
       <%= label_tag :card_code, "Security Code on Card (CVV)" %>
       <%= text_field_tag :card_code, nil, name: nil, "data-stripe" => "cvc" %>
     </div>
     <div class="field">
       <%= label_tag :card_month, "Card Expiration" %>
       <%= text_field_tag :card_month, nil, name: nil, "data-stripe" => "exp-month", class: "input-mini", "placeholder" => "MM" %>
      <%= text_field_tag :card_year, nil, name: nil, "data-stripe" => "exp-year", class: "input-mini", "placeholder" => "YYYY" %>
     </div>
   <% end %>
   <div id="stripe_error">
     <noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
   </div>
   <div class="actions">
     <%= f.submit "Subscribe", class: "btn btn-primary" %>
   </div>
 <% end %>

subcriptions_controller.rb

    class SubscriptionsController < ApplicationController

  def index
    @subscriptions = Subscription.all
  end

  def show
    @subscription = Subscription.find(params[:id])
  end

  def new
    plan = Plan.find(params[:plan_id])
    @subscription = plan.subscriptions.build
  end

  def create
    @subscription = Subscription.new(subscription_params)
    if @subscription.save_with_payment
      redirect_to @subscription, :notice => "Thank you for subscribing!"
    else
      render :new
    end
  end

  private
    def subscription_params
      params.require(:subscription).permit(:plan_id, :email, :stripe_card_token)
    end
end

模型订阅.rb

class Subscription < ActiveRecord::Base
  before_save { self.email = email.downcase }
  belongs_to :plan
  validates_presence_of :plan_id
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }

  attr_accessor :stripe_card_token

  def save_with_payment
    if valid?
      customer = Stripe::Customer.create(card: stripe_card_token, email: email, plan: plan_id)
      self.stripe_customer_token = customer.id
      save!
    end
  rescue Stripe::InvalidRequestError => e
    logger.error "Stripe error while creating customer: #{e.message}"
    errors.add :base, "There was a problem with your credit card."
    false
  end
end

最后,javascript(主要来自 stripe 的文档,但略有修改):

// This identifies your website in the createToken call below
Stripe.setPublishableKey('<%= Rails.configuration.stripe[:publishable_key] %>');

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

  if (response.error) {
    // Show the errors on the form
    $form.find('#stripe_error').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.find($('#subscription_stripe_card_token').val(token));
    // and re-submit
    $form.get(0).submit();
  }
};

jQuery(function($) {
      $('#new_subscription').submit(function(e) {
        var $form = $(this);

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

        Stripe.createToken($form, stripeResponseHandler);

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

谢谢阅读!任何帮助将不胜感激。

4

1 回答 1

4

好的,所以我弄清楚这里发生了什么。经过更多的测试,我意识到如果我在页面上点击刷新,然后填写表单并提交,它每次都能正常工作。但是,如果我通过应用程序导航到 subscription_path,它将产生错误,除非您在到达那里后手动刷新页面。

所以...经过大量挖掘后,我发现问题出在 Turbolinks 上。这篇文章帮助我弄清楚了如何解决这个问题:Rails 4: how to use $(document).ready() with turbo-links。据我所知,jQuery 没有加载 Stripe.js,因为 turbo-links。

有几个选项可以解决它。

  1. 禁用涡轮链接
  2. 向您的 javascript 添加一些代码(请参阅上面的链接)
  3. 添加 jquery-turbolinks gem,它可以帮助 jQuery 很好地使用 turbo-links。

(我选择了选项 3,因为它似乎是最简单的解决方案)。

无论如何,现在表格有效!

于 2013-11-10T20:16:06.213 回答