0

我尝试在 rails 应用程序中使用自定义表单来实现 Stripe。我有一个“计划”页面,允许用户选择他想要的计划。它使用 get 参数中的计划名称重定向到收费自定义表单。

当我提交表单时,我收到以下错误:

该客户没有附加付款来源

但是,如果我重新加载表单并再次提交,它工作得很好......

知道问题出在哪里吗?

自定义表格:

<%= form_tag charges_path, method: 'post', id: 'payment-form' do %>   <span class="payment-errors"></span>

  <label class="amount">
      <span>Amount: <%= pretty_amount(@amount) %></span>
    </label>

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

  <input type="hidden" name="plan" value="<%= params['plan'] %>" />

  <button type="submit">Submit Payment</button> <% end %>

资产/javascripts/charges.coffee

jQuery ($) ->
  $('#payment-form').submit (event) ->
    $form = $(this)
    # Disable the submit button to prevent repeated clicks
    $form.find('button').prop 'disabled', true
    Stripe.card.createToken $form, stripeResponseHandler
    # Prevent the form from submitting with the default action
    false
  return

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

收费控制器:

class ChargesController < ApplicationController
  before_action :set_plan
  before_action :amount_to_be_charged
  before_action :set_description
  before_action :authenticate_user!

  def new
  end

  def create
    if @plan == "plan1-yearly"
      StripeTool.create_membership(email: current_user.email,
                                   stripe_token: params[:stripeToken],
                                   plan: @plan,
                                   description: current_user.id)
    elsif @plan == "plan1-monthly"
      StripeTool.create_membership(email: current_user.email,
                                   stripe_token: params[:stripeToken],
                                   plan: @plan,
                                   description: current_user.id)
    end

    redirect_to charge_thanks_path

  rescue Stripe::CardError => e
    flash[:alert] = e.message
    redirect_to new_charge_path
  end

  def thanks
  end

  def plan
  end

  private

    def set_plan
      if params['plan'].present? == false
        @plan = @plan
      else
        @plan = params['plan']
      end
    end

    def set_description
      if @plan == "plan1-yearly"
        @description = "Startup Yearly Plan"
      elsif @plan == "plan1-monthly"
        @description = "Startup Monthly Plan"
      end
    end

    def amount_to_be_charged
      if @plan == "plan1-yearly"
        @amount = 22680
      elsif @plan == "plan1-monthly"
        @amount = 2350
      end
    end
end

在我的应用程序布局中:

<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
    <script type="text/javascript">
      Stripe.setPublishableKey('<%= ENV['STRIPE_PUBLISHABLE_KEY'] %>');
    </script>

谢谢。

4

2 回答 2

0

我会从 Stripe 文档中看一下这里的内容:

https://stripe.com/docs/stripe.js/v2#card-createToken

我认为这里缺少的是与 StripeResponseHandler 交互的 JS 调用。我会尝试替换这个: Stripe.card.createToken $form, stripeResponseHandler

有了这个:

Stripe.card.createToken({
  number: $('.card-number').val(),
  cvc: $('.card-cvc').val(),
  exp_month: $('.card-expiry-month').val(),
  exp_year: $('.card-expiry-year').val()
}, stripeResponseHandler);
于 2017-08-25T16:30:52.040 回答
0

好的,所以我在视图末尾添加了脚本,现在它可以工作了。

于 2017-08-26T07:07:58.287 回答