The strip symbol does not transfer to controller rails 4

Problem

I tested CoffeeScript, and the form calls Stripe, sets the hidden field with the appropriate response marker and submits the form. My problem is that as soon as its presented controller does not seem to catch the token correctly and throws this error: Stripe :: InvalidRequestError - you must specify either a card or a client identifier .

Then I got tired, taking the marker that was generated, and hard-coded it in the controller to make sure it worked. I submitted a form that worked, and payment was received at the end of the Stripes. I hardly understand what to do next. I am wondering if I forget something or something is missing, because payments are invested in assigned tasks.

Gem Versions

  • Ruby: 2.1.0
  • Rails: 4.0.1
  • Stripe: 1.9.9

Files

/payment/new.html.erb

<%= form_for([@assignment, @payment]) do |f| %>
  <% if @payment.errors.any? %>
    <div class="error_messages">
      <h2><%= pluralize(@payment.errors.count, "error") %> prohibited this subscription from being saved:</h2>
      <ul>
        <% @payment.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.hidden_field :stripe_customer_token %>

  <% if @payment.stripe_customer_token.present? %>
    <p>This assignment has already been paid for.</p>
  <% else %>

    <div class="field">
      <%= label_tag :card_number, "Credit Card Number" %>
      <%= text_field_tag :card_number, nil, name: nil, placeholder: "00000000000000" %>
    </div>
    <div class="row">
      <div class="field card__dates">
        <%= label_tag :card_month, "Card Expiration" %>
        <%= select_month nil, {add_month_numbers: 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="field card__cvv">
        <%= label_tag :card_code, "CVV" %>
        <%= text_field_tag :card_code, nil, name: nil, placeholder: "003", required: true, maxlength: 4, minlength: 3 %>
      </div>
    </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 class="actions">
    <%= f.submit "Pay " + number_to_currency(@assignment.price.to_s), class: 'btn btn__primary btn__large btn--fill' %>
  </div>

payment_controller.rb

class PaymentsController < ApplicationController
  def new
    set_assignment
    @payment = @assignment.build_payment
    @price = @assignment.price
  end

  def create
    set_assignment
    @payment = @assignment.build_payment(payment_params)

    if save_with_payment
      redirect_to assignments_path, :notice => "Payment received, Thank you!"

      # since payment was successful, set assignment paid to true
      Assignment.update(@assignment, assignment_paid: true, project_status: "In Progress")
    else
      render :new
    end
  end

  private

    def save_with_payment

      # Set your secret key: remember to change this to your live secret key in production
      # See your keys here https://manage.stripe.com/account
      Stripe.api_key = Rails.configuration.stripe[:secret_key]

      # Get the credit card details submitted by the form
      token = params[:stripe_customer_token]

      # How much the assignment costs, which must be converted to cents
      @amount = (@price * 100)

      # Create the charge on Stripe servers - this will charge the user card
      begin
        charge = Stripe::Charge.create(
          :amount => @amount,
          :currency => "cad",
          :card => token,
          :description => "some description of the product"
        )
      rescue Stripe::CardError => e
        redirect_to @assignment, :notice => "The card has been declined"
      end
    end

    def set_assignment
      @assignment = Assignment.friendly.find(params[:assignment_id])
    end

    def payment_params
      params.require(:payment).permit(
        :stripe_customer_token
      )
    end
end

payment.js.coffee

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

payment =
  setupForm: ->
    $('#new_payment').submit ->
      $('input[type=submit]').attr('disabled', true)
      if $('#card_number').length
        payment.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, payment.handleStripeResponse)

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

payment.rb

class Payment < ActiveRecord::Base
  belongs_to :assignment
end
+4
source share
1 answer

At least two problems that I saw. And I think there can be more after that.

  • You do not have access to the paramsinside#save_with_payment

    The problem occurs in this line:

    # Get the credit card details submitted by the form
    token = params[:stripe_customer_token]
    

    Parameters are protected by strong_parameters, and you do not have access to them.

    The fix is ​​to allow all the necessary parameters in payment_paramsand reuse it in this method.

  • In fact, you do not have @priceinside#create

    This problem is not directly related to the issue, but exists.

    @price #new. #create - , .

    , payment_params

+2

All Articles