stripeToken 没有返回到我的表单中

stripeToken is not being returned to my form

我的 Stripe 集成设置正确,因为它确实 return 一个错误 This customer has no attached payment source,这是一个 Stripe 错误,表明表单没有 return 足够的付款信息。

这是我的 subscriptions.js.coffee:

stripeResponseHandler = (status, response) ->
  $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
    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()
  return

jQuery ($) ->
  $('payment-form').submit (event) ->
    $form = $(this)
    $form.find('button').attr 'disabled', true
    Stripe.card.createToken $form, stripeResponseHandler
    false
  return

这是我在 new.html.erb:

的表格
<% unless @subscription.errors.blank? %>
  <%= @subscription.errors.full_messages.to_sentence %>
<% end %>

<h2>Subcribing to <%= @plan.name %></h2>

<%= form_for @subscription, html: {id: 'payment-form'} do |f| %>
  <input type="hidden" name="plan_id", value="<%= @plan.id %>" />
  <span class="payment-errors"></span>

  <div class="form-row">
    <label>
      <span>Email Address</span>
      <input type="email" size="20" name="email_address" />
    </label>
  </div>

  <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>

  <button type="submit">Pay Now</button>
<% end %>

这是SubscriptionsController#Create:

  def create
    @plan = Plan.find(params[:plan_id])
    @subscription = CreateSubscription.call(
      @plan,
      params[:email_address],
      params[:stripeToken]
    )
    if @subscription.errors.blank?
      flash[:notice] = "Thank you for your purchase! Please click the link in the email we just sent you to get started."
      redirect_to authenticated_root_path
    else
      render :new
    end
  end

上面称这个app/services/create_subscription.rb:

class CreateSubscription
  def self.call(plan, email_address, token)
    user, raw_token = CreateUser.call(email_address)

    subscription = Subscription.new(
      plan: plan,
      user: user
    )

    begin
      stripe_sub = nil
      if user.stripe_customer_id.blank?
        binding.pry
        customer = Stripe::Customer.create(
          source: token,
          email: user.email,
          plan: plan.stripe_id
        )

        user.stripe_customer_id = customer.id
        user.save!
        stripe_sub = customer.subscriptions.first
      else
        customer = Stripe::Customer.retrieve(user.stripe_customer_id)
        stripe_sub = customer.subscriptions.create(
          plan: plan.stripe_id
        )
      end

      subscription.stripe_id = stripe_sub.id

      subscription.save!
    rescue Stripe::StripeError => e
      subscription.errors[:base] << e.message
    end

    subscription
  end
end

我知道表格没有收到 stripeToken 的原因是因为当我在那个 create 中使用 binding.pry 并这样做时:

00:52:31 web.1              |     14: def create
00:52:31 web.1              |     15:   @plan = Plan.find(params[:plan_id])
00:52:31 web.1              |  => 16:   binding.pry
00:52:31 web.1              |     17:   @subscription = CreateSubscription.call(
00:52:31 web.1              |     18:     @plan,
00:52:31 web.1              |     19:     params[:email_address],
00:52:31 web.1              |     20:     params[:stripeToken]
00:52:31 web.1              |     21:   )
00:52:31 web.1              |     22:   if @subscription.errors.blank?
00:52:31 web.1              |     23:     flash[:notice] = "Thank you for your purchase! Please click the link in the email we just sent you to get started."
00:52:31 web.1              |     24:     redirect_to authenticated_root_path
00:52:31 web.1              |     25:   else
00:52:31 web.1              |     26:     render :new
00:52:31 web.1              |     27:   end
00:52:31 web.1              |     28: end
00:52:31 web.1              | 
[1] pry(#<SubscriptionsController>)> params
00:52:37 web.1              | => {"utf8"=>"✓", "plan_id"=>"1", "email_address"=>"someuser@test.com", "action"=>"create", "controller"=>"subscriptions"}

注意没有params[:stripeToken].

此外,当我在 create_subscription.rb 服务中尝试 binding.pry 时,我得到的是:

00:52:41 web.1              |     10:     begin
00:52:41 web.1              |     11:       stripe_sub = nil
00:52:41 web.1              |     12:       if user.stripe_customer_id.blank?
00:52:41 web.1              |  => 13:         binding.pry
00:52:41 web.1              |     14:         customer = Stripe::Customer.create(
00:52:41 web.1              |     15:           source: token,
00:52:41 web.1              |     16:           email: user.email,
00:52:41 web.1              |     17:           plan: plan.stripe_id
00:52:41 web.1              |     18:         )
00:52:41 web.1              | 
[1] pry(CreateSubscription)> token
00:52:44 web.1              | => nil

可能是什么原因造成的,我该如何解决?

事实证明,我的问题是一个愚蠢的错误。

在我的 CoffeeScript 中注意我有这个:

jQuery ($) ->
  $('payment-form').submit (event) ->
    $form = $(this)
    $form.find('button').attr 'disabled', true
    Stripe.card.createToken $form, stripeResponseHandler
    false
  return

问题出在表单选择器中。我没有将 # 添加到表单的 ID。

所以一旦我更改了这一行:

  $('payment-form').submit (event) ->

为此:

  $('#payment-form').submit (event) ->

它就像一个魅力。

卫生部! 打脸