Users :: RegistrationsController #crera中的Stripe :: InvalidRequestError

时间:2015-08-13 12:34:35

标签: ruby-on-rails ruby forms

我没有再收到任何错误,但我知道当我创建一个新用户时,stripeToken不会被写入。

控制器/用户/ registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController                      

    def create
        super do |resource|
        if params[:plan]
            resource.plan_id == params[:plan]
        if resource.plan_id == 1
            resource.save_with_payment
        else
            resource.save
        end
       end
     end
   end

模型/ user.rb

class Users < ActiveRecord::Base

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable
belongs_to :plan
attr_accessor :stripeToken

    def payment
    if valid?
      customer = Stripe::Customer.create(
          description: email,
          plan: plan_id,
          card: stripeToken
      )
      self.stripeToken = customer.id
      save!
    end
  end
 end

资产/ JavaScript的/ users.js

$(document).ready(function() {
   Stripe.setPublishableKey($('meta[name="stripe-key"]').attr("content"));
    // Watch for a form submission
    $("#form-submit-btn").click(function(event) {
        event.preventDefault();
        $("input[type=submit]").prop("disabled", true);
        var error = false;
        var ccNum = $("#card_number").val(),
            cvcNum = $("#card_code").val(),
            expMonth = $("#card_month").val(),
            expYear = $("#card_year").val();

        if (!error) {
            // Get the Stripe token:
            Stripe.createToken({
                number: ccNum,
                cvc: cvcNum,
                exp_month: expMonth,
                exp_year: expYear
            }, stripeResponseHandler);
        }
        return false;
    }); // form submission

    function stripeResponseHandler(status, response) {
        // Get a reference to the form:
        var f = $("#new_user");

        // Get the token from the response:
        var token = response.id;

        // Add the token to the form:
        f.append('<input type="hidden" name="user[stripe_card_token]" value="' + token + '" />');

        // Submit the form:
        f.get(0).submit();
    }
});

视图/布局/ application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>tinito</title>
  <%= stylesheet_link_tag    "application", media: "all" %>
  <%= javascript_include_tag "https://js.stripe.com/v2/", type: "text/javascript"  %>
  <%= javascript_include_tag "application" %>
  <%= tag :meta, name: "stripe_api_key", content: STRIPE_PUBLISHABLE_KEY  %>
  <%= csrf_meta_tags %>
</head>
<body>

<%= render "layouts/header" %>

<% flash.each do |key, value| %>
    <%= content_tag :div, value, class: "alert alert-#{key}" %>
<% end %>
    <%= yield %>
<%= render "layouts/footer" %>

</body>
</html>

视图/设计/注册/ _pro_form.html.erb

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
    <%= devise_error_messages! %>

    <%= hidden_field_tag "plan", params[:plan] %>

    <div class="field form-group">
      <%= f.label :email %><br />
      <%= f.email_field :email, autofocus: true, placeholder: "Email", class: "form-control" %>
    </div>

    <div class="field form-group">
      <%= f.label :password %>
      <% if @minimum_password_length %>
          <em>(<%= @minimum_password_length %> characters minimum)</em>
      <% end %><br />
      <%= f.password_field :password, autocomplete: "off", placeholder: "Password", class: "form-control" %>
    </div>

    <div class="field form-group">
      <%= f.label :password_confirmation %><br />
      <%= f.password_field :password_confirmation, autocomplete: "off", placeholder: "Confirm Password", class: "form-control" %>
    </div>

    <div class="form-group">
      <%= label_tag :card_number, "Credit Card Number" %>
      <%= text_field_tag :card_code, nil, name: nil, placeholder: "41*****", class: "form-control" %>
    </div>

    <div class="form-group">
      <%= label_tag :card_code, "Security Code on Card (CVV)" %>
      <%= text_field_tag :card_number, nil, name: nil, placeholder: "123", class: "form-control" %>
    </div>

    <div class="form-group">
      <%= label_tag :card_month, "Card Expiration" %>
      <%= select_month nil, {add_month_number: true},{name: nil, id: "card_month"} %>
      <%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %>
    </div>

    <div class="actions form-group">
      <%= f.submit "Sign up", class: "btn btn-primary", id: "form-submit-btn" %>
    </div>
<% end %>

控制器/ application_controller.rb

 class ApplicationController < ActionController::Base
   protect_from_forgery with: :exception



    before_filter :configure_permitted_parameters, if: :devise_controller?

      protected

      def configure_permitted_parameters
        devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:name, :stripeToken, :email, :password, :password_confirmation) }
      end
    end

分贝/迁移/ ***** _ add_stripe_token_to_users.rb

class AddStripeTokenToUsers < ActiveRecord::Migration
 def change
    add_column :users, :stripeToken, :string
  end
end

3 个答案:

答案 0 :(得分:2)

在以下位置为您的form_for添加ID: views / devise / registrations / _pro_form.html.erb

<%= form_for(resource, as: resource_name, :html => {:id => "payment-form"}, url: registration_path(resource_name)) do |f| %>

还要添加

<div class="payment-errors text-danger"></div>

这将显示Stripe的错误响应。更新 User.js 以处理错误响应,如@vivrass所述。

$(document).ready(function() {
  Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'));
  // Watch for a form submission:
  $("#form-submit-btn").click(function(event) {
    event.preventDefault();
    $('input[type=submit]').prop('disabled', true);
    var error = false;
    var ccNum = $('#card_number').val(),
        cvcNum = $('#card_code').val(),
        expMonth = $('#card_month').val(),
        expYear = $('#card_year').val();
    if (!error) {
      // Get the Stripe token:
      Stripe.createToken({
        number: ccNum,
        cvc: cvcNum,
        exp_month: expMonth,
        exp_year: expYear
      }, stripeResponseHandler);
    }
    return false;
  }); // form submission
  function stripeResponseHandler(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 {
      // response contains id and card, which contains additional card details
      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 submit
      $form.get(0).submit();
    }
  };
});

最后......你最有可能用旧卡测试。如果您使用的是卡号41111111111111111 cvv123,您将收到Stripe的错误响应,说明“您的卡号不正确”。

使用此处的更新测试卡:https://stripe.com/docs/testing

答案 1 :(得分:0)

您是否尝试检查表单提交中的rails日志是否将条带标记作为参数传递?

可能是因为你没有将它包含在强参数中而被过滤掉。

答案 2 :(得分:0)

你的问题可能是在“var token = response.id;”行的Javascript中。您是否验证了收到的条纹响应?

Stripe文档验证您的实施中缺少Stripe请求是否有错误(https://stripe.com/docs/tutorials/forms

function stripeResponseHandler(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 {
    // response contains id and card, which contains additional card details
    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 submit
    $form.get(0).submit();
  }
};