Unable to create/generate a stripe_card_token

2019-12-16 20:05发布

问题:

I am creating a stripe_card_token with:

Stripe.createToken(card, charge.handleStripeResponse)

In my charges.js.coffee file

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

charge =
  setupForm: ->
    $('#new_charge').submit ->
      $('input[type=submit]').attr('disabled', true)
      if $('#card_number').length
        charge.processCard()
        false
      else
        true

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

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

This is my charges model:

class Charge < ActiveRecord::Base

    attr_accessor :stripe_card_token

    belongs_to :contest
    belongs_to :user

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

However when I click the donate button I get the notice(& redirect to root_path) as stated in my controller: "Transaction was not able to be recorded"

This is my charges controller:

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

When I look at my log I get this error:

Started POST "/charges" for 127.0.0.1 at 2014-06-11 01:10:29 -0700
Processing by ChargesController#create as HTML
  Parameters: {"utf8"=>"√", "authenticity_token"=>"9bqk2Q6HBM1ehL4JPgncNQ3gnP0X1nQK2y6ENm8Yb8g=", "c
harge"=>{"contest_id"=>"31", "user_id"=>"", "amount"=>"40", "stripe_card_token"=>""}, "card_number"=
>"4242424242424242", "card_code"=>"419", "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 502ms (ActiveRecord: 0.0ms)


Started GET "/" for 127.0.0.1 at 2014-06-11 01:10:30 -0700

For some reason the stripe card token in not being generated...

This is my charges/new form:

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

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

I have the following in the head section of my layout:

 <%= javascript_include_tag "https://js.stripe.com/v1/", "application", "data-turbolinks-track" => true %>
    <%= csrf_meta_tags %>

    <%= tag :meta, :name => "stripe-key", :content => STRIPE_PUBLIC_KEY %>

This is my charges table:

  create_table "charges", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "stripe_charge_token"
    t.integer  "contest_id"
    t.integer  "user_id"
    t.decimal  "amount"
  end

In my config/initializers/stripe.rb I have:

Stripe.api_key = "sk_testdfkdlfjgkdlsuEvpipr2umoKu9f"
STRIPE_PUBLIC_KEY = "pk_testdfgkdfgpud6JHfCvuRHnvpuLPo"

What am I doing wrong??

回答1:

So, first, as previously mentioned, you need to make sure your form doesn't have name attributes for the credit card details so that that information doesn't hit your server. You just need the token on the server, not the credit card number, CVC, or expiration.

Second, to debug this, I'd stop the submission of the form (after the Stripe token request) and check that the hidden input is being populated with a token from Stripe. Then I'd confirm that the token is getting to the server.

Hope that helps! Larry

PS I work on Support at Stripe.