簡體   English   中英

創建客戶時出現條帶錯誤:您為“ card”傳遞了一個空字符串

[英]Stripe error while creating customer: You passed an empty string for 'card'

Stripe不接受付款,收費一直失敗。 我收到此錯誤:

Started POST "/charges" for 127.0.0.1 at 2014-06-09 06:30:58 -0700
Processing by ChargesController#create as HTML
  Parameters: {"utf8"=>"√", "authenticity_token"=>"9bqk2Q6NEM1ehHDJPgncNQ3gnP0X1hQK6y6ENm3Yb1g=", "c
harge"=>{"contest_id"=>"36", "user_id"=>"", "amount"=>"12", "stripe_card_token"=>""}, "card_number"=
>"4242 4242 4242 4242", "card_code"=>"478", "button"=>""}
Stripe error while creating customer: You passed an empty string for 'card'. We assume empty values
are an attempt to unset a parameter; however 'card' cannot be unset. You should remove 'card' from y
our request or supply a non-empty value
Redirected to http://localhost:3000/
Completed 302 Found in 477ms (ActiveRecord: 0.0ms)

似乎可能沒有創建條紋令牌? 這里發生了什么?

這是我的表格:

 <% content_for :head do %>
        <%= tag :meta, :name => "stripe-key", :content => STRIPE_PUBLIC_KEY %>
    <% end %>
    <%= form_for @charge, :html => { :class => 'form' } do |f| %>
        <div class="form-inputs">
            <div class="row">
                <%= f.hidden_field :contest_id, value: @contest.id  %>
                <%= f.hidden_field :user_id %>
                <%= f.hidden_field :amount %>
                <!-- TODO CHANGE THIS ACCORDINGLY  -->
                <%= f.hidden_field :stripe_card_token %>
                <div class="small-12 medium-6 large-2 columns">
                    <%= f.label "Amount:", class: "text-right" %>
                </div>
                <div class="small-12 medium-6 large-10 columns" style="margin-bottom: 0.5rem; margin-top: 0.5rem;">
                    <%= number_to_currency(@charge.amount, :unit => "$") %>
                </div>
                <% if @charge.stripe_card_token.present? %>
                  Credit card has been provided.
                <% else %>
                  <div class="small-12 medium-6 large-2 columns">
                    <%= label_tag :card_number, "Credit Card Number:", class: "text-right" %>
                  </div>
                  <div class="small-12 medium-6 large-10 columns">
                    <%= text_field_tag :card_number %>
                  </div>
                  <div class="small-12 medium-6 large-2 columns">
                    <%= label_tag :card_code, "Security Code on Card (CVV):", class: "text-right" %>
                  </div>
                  <div class="small-12 medium-6 large-10 columns end">
                    <%= text_field_tag :card_code %>
                  </div>
                  <div class="small-12 medium-6 large-2 columns">
                    <%= label_tag :card_month, "Card Expiration:", class: "text-right" %>
                  </div>
                  <div class="small-6 medium-3 columns">
                    <%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %>
                  </div>
                  <div class="small-6 medium-3 columns">
                    <%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %>
                  </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>
            <div class="row">
                <div class="form-actions small-9 small-offset-2 columns">
                    <%= button_tag :type => "button", :class => "radius" do  %>
                        <%= link_to "Back", @contest, :style => "color: white" %>
                    <% end %>
                    <%= f.button :Donate, :class => "radius" %>
                </div>
            </div>
        </div>
    <% end %>
    <% content_for :js do %>
        <%= javascript_include_tag "https://js.stripe.com/v1", "application" %> 
        <%= javascript_include_tag asset_path("stripe/stripe.js"), "application" %>
    <% end %>

這是我的費用控制者:

class ChargesController < ApplicationController

    def new
      @contest = Contest.find(params[:id])
      @charge = Charge.new(amount: params[:amount])
    end

    def create
      @charge = Charge.new(charges_params)
      if @charge.save_with_payment(@charge)
        redirect_to root_path, :notice => "Contribution was recorded succesfully!"
      else
        redirect_to root_path, :notice => "Transaction was not able to be recorded"
      end
    end

    def charges_params
        params.require(:charge).permit(:stripe_card_token, :contest_id, :user_id, :amount)
    end

end

我的收費模式:

class Charge < ActiveRecord::Base

    attr_accessor :stripe_card_token

    belongs_to :contest
    belongs_to :user

    def save_with_payment(charge)
      if valid?
        Stripe::Charge.create(
          :amount => (charge.amount.to_i)*100,
          :currency => "usd",
          :card => stripe_card_token);
        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

很可能看起來stripe_card_token是空白的,因為它的

:card => stripe_card_token

嘗試將其更改為

:card => charge.stripe_card_token

stripe_card_token為空白無關,您的服務器當前在PCI范圍內,因為它正在接收卡號和CVV代碼。 如果使用Stripe,這可能不是您想要的。

Stripe入門文檔

請注意,代表敏感卡數據(數字,CVC,到期月份和年份)的輸入字段如何不具有“名稱”屬性。 這樣可以防止他們在提交表單時訪問您的服務器。

默認情況下,Rails標簽助手會生成一個name屬性。 在這種情況下,這是不可取的。

您可以通過為namevalue傳遞nil並定義某種標識符來覆蓋此行為:

<%= text_field_tag nil, nil, 'data-stripe' => 'card_number' %>

在這里,我使用了Stripe當前推薦的data-stripe ,但您也可以使用id屬性(如其較早的教程所推薦)。

回到最初的問題,問題出在計費模型中,在這里您要覆蓋Active Record並屏蔽數據庫中的數據:

class Charge < ActiveRecord::Base

    attr_accessor :stripe_card_token     # Don't do this!

attr_accessor永遠不要在數據庫列上使用。 Active Record提供了自己的訪問器,以便從數據庫中提取數據。 通過在此處聲明訪問器,您將用Ruby的基本功能替換Active Record的功能:

irb(main):001:0> Charge.first
  Charge Load (0.3ms)  SELECT  "charges".* FROM "charges"   ORDER BY "charges"."id" ASC LIMIT 1
=> #<Charge id: 1, stripe_card_token: "0xdeadbeef", created_at: "2014-06-11 14:27:40", updated_at: "2014-06-11 14:27:40">
irb(main):002:0> c.stripe_card_token
=> nil

話雖這么說,但是您開始使用Railscast已有將近三年的歷史,它違反了各地的最佳做法,並使用了過時的API端點。 校正模型后,與使用Stripe當前的教程和文檔相比,啟動表格和JavaScript還是更好的選擇。

我遇到了同樣的問題。
我的subscription.js.coffee:

jQuery ->
  Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
  subscription.setupForm()

subscription =
  setupForm: ->
    $('#new_subscription').submit (e) ->
      $('input[type=submit]').attr('disabled', true)
      subscription.processCard()
      return false

  processCard: ->
    card =
      number: $('#card_number').val()
      cvc: $('#card_code').val()
      expMonth: $('#card_month').val()
      expYear: $('#card_year').val()
    Stripe.createToken(card, subscription.handleStripeResponse)

  handleStripeResponse: (status, response) ->
    if status == 200
      $('#subscription_stripe_card_token').val(response.id)
      $('#new_subscription')[0].submit()
    else
      $('#stripe_error').text(response.error.message) 
      $('input[type=submit]').attr('disabled', false)
      false

如您所見,當用戶按下“ submit按鈕時,將$('#new_subscription').submit (e)函數。 提交功能中幾乎所有的條帶魔術。

在我的情況下,有時不會引發stripe_card_toke函數,因此stripe_card_toke空的stripe_card_toke參數發送到您的服務器。

奇怪的行為是由Rails turbolinks設施引起的。
我是這樣解決的:

  1. Gemfile中添加一行:
    gem 'jquery-turbolinks'
  2. 在清單application.js中添加一行:
    //= require jquery.turbolinks
    所以我的application.js看起來像:
 //= require jquery //= require jquery.turbolinks //= require jquery_ujs //= require turbolinks //= require bootstrap //= require jquery_nested_form //= require_tree . 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM