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!"
Assignment.update(@assignment, assignment_paid: true, project_status: "In Progress")
else
render :new
end
end
private
def save_with_payment
Stripe.api_key = Rails.configuration.stripe[:secret_key]
token = params[:stripe_customer_token]
@amount = (@price * 100)
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