Getting Stripe working in Rails 4 - ruby-on-rails

I am trying to set up stripe in rails and I can enter in the credit card info but when it redirects I get the following error:
No route matches [POST] "/enrollment/1"
I am confused because when I rake routes I get:
enrollment_index GET /enrollment(.:format) enrollment#index
POST /enrollment(.:format) enrollment#create
new_enrollment GET /enrollment/new(.:format) enrollment#new
edit_enrollment GET /enrollment/:id/edit(.:format) enrollment#edit
enrollment GET /enrollment/:id(.:format) enrollment#show
PATCH /enrollment/:id(.:format) enrollment#update
PUT /enrollment/:id(.:format) enrollment#update
DELETE /enrollment/:id(.:format) enrollment#destroy
So I am confused why it is trying to post because in my view, I specify that the method should be put:
<div class='container'>
<div class='jumbotron enroll-page'>
<div class='row'>
<h1>Enroll Here</h1>
<%= form_tag enrollment_path(1), :method => :put do %>
<article>
<label class="amount">
<span>Amount: $5.00</span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500"></script>
<% end %>
</div>
</div>
</div>
My controller looks like this:
class EnrollmentController < ApplicationController
before_filter :authenticate_user!, unless: :admin_signed_in?
def new
end
def create
#get credit card details submitted by form
token = params[:stripeToken]
customer = Stripe::Customer.create(
:card => token,
:plan => 3455,
:email => current_user.email
)
current_user.paid = true
current_user.stripeid = customer.id
current_user.save
redirect_to courses_path, :notice => 'Your enrollment is complete!'
end
end
Thanks so much for any help that you can give!
EDIT: I think I have it. Ajay was totally right that this works better if I name the controller "enrollments" instead of enrollment. In the new.html.erb view, it should look like this instead:
<div class='container'>
<div class='jumbotron enroll-page'>
<div class='row'>
<h1>Enroll Here</h1>
<%= form_tag enrollments_path do %>
<article>
<label class="amount">
<span>Amount: $5.00</span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500"></script>
<% end %>
</div>
</div>
</div>

check in routes the resource must be enrollments not enrollment
#routes.rb
resources :enrollments
Now when you run
rake routes | grep 'enrollment'
new_enrollment GET /enrollments/new(.:format) enrollments#new
#app/controller/enrollments_controller.rb
class EnrollmentsController < ApplicationController
def new
#enrollment = Enrollment.new
end
def edit
#enrollment = Enrollment.where(id: params[:id]).first
end
def create
#catch your params and do whatever.
end
def update
# catch your params and do your operation.
end
end
Now comes the View :
app/views/enrollments/new.html.erb
<%= render 'form %>
app/views/enrollments/edit.html.erb
<%= render 'form' %>
now in your app/views/enrollments/_form.html.erb
<%= form_tag(#enrollment)do %>
<%= label_tag :amount %>
<%= text_field_tag :amount, 50.00 %>
<%= submit_tag %>
<% end %>
In your console, the log should be something like this :
Started GET "/enrollments/new" for 127.0.0.1 at 2015-01-10 06:18:08 +0530
Processing by EnrollmentsController#new as HTML
This confirms you are hitting the new page not the edit. Check it !
Inspect your form, this should look like this, check it.

Related

Stripe Elements Charges not associated to Rails5 Devise current_user - Stripe::InvalidRequestError in CheckoutsController#create

I have Stripe integrated with Stripe Gem and I can successfully create charges and a Stripe user; I just can't get the two to have an association. If I associate the :source => params[:stripeToken] the charge goes through, but if I associate it with my user model :source => current_user.stripe_customer, I get a No such token: cus_BX2RXGoOVkpvhL error.
Here are my request parameters when associating with my user model.
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"/KI7rzkJsM2uXIynoZkWKa1L+kNgyVcw+UsqfPNOnLYO3t4vfL+R7Yb4XhonyhwTbqlyWTtgYjey71ZroSmoRA==",
"charge"=>"2200",
"stripeToken"=>"tok_1B9yneHbiQgBeZWGq78mXM2l",
"card_brand"=>"Visa",
"card_exp_month"=>"4",
"card_exp_year"=>"2024",
"card_last4"=>"4242"}
views/donations/show.html.erb
...
<%= link_to 'Confirm Donation', new_checkout_path(charge: #donation.amount), class: 'btn btn-primary' %>
...
views/checkouts/new.html.erb
<section>
<h1>Secure Payment</h1>
<div class="pages-content">
<% if current_user.card_last4? %>
<%= form_tag checkout_path, id: 'existing-card' do %>
<p>Pay with existing card:</p>
<div><strong>Card on file:</strong>
<%= current_user.card_brand %> (**** **** **** <%= current_user.card_last4 %>)
</div>
<div><strong>Expiration:</strong> <%= current_user.card_exp_month %> / <%= current_user.card_exp_year %></div>
<p>or <%= link_to 'add a new card', '#', class: 'show-card-form' %></p>
<%= hidden_field_tag :charge, params[:charge] %>
<input type="submit" class="btn btn-default" value="Submit Payment">
<% end %>
<% end %>
<%= form_tag checkout_path, id: 'payment-form', style: (current_user.card_last4? ? 'display:none' : nil) do %>
<div class="stripe-wrapper">
<div class="form-row">
<label for="card-element">
Enter Your Credit or Debit Card
</label>
<div id="card-element">
<!-- a Stripe Element will be inserted here. -->
</div>
<%= hidden_field_tag :charge, params[:charge] %>
<!-- Used to display Element errors -->
<div id="card-errors" role="alert"></div>
</div>
<button>Submit</button>
</div>
<% end %>
</div>
</section>
models/user.rb
class User < ApplicationRecord
...
def stripe_customer
if stripe_id?
Stripe::Customer.retrieve(stripe_id)
else
stripe_customer = Stripe::Customer.create(email: email)
update(stripe_id: stripe_customer.id)
stripe_customer
end
end
You need to do this instead, if you're charging the Customer by ID:
:customer => current_user.stripe_customer
I had a similar problem once and i remember that it was because my partner was using a different [Publishable key] on Testing mode, So i gave him mine and it worked, I would like you to make sure that the user is already exists on stripe.
I hope this help you.

Stripe iFrame being blocked - rails and stripe

I am making a checkout form with stripe and rails. I have a shop_controller that serves a list of products in the shop#index. Then that leads to the shop#show where the stripe form is located, and users can purchase a product.
Right now when clicking the button to make a purchase (using the fake card stripe gives you), all that happens is the button endlessly spins, and I get the following errors in the console:
GET https://checkout.stripe.com/api/account/lookup?email=MYEMAILADDRESS&key=&locale=en-US 400 (Bad Request)
and
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://localhost:3000" from accessing a frame with origin "https://checkout.stripe.com". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "https". Protocols must match.
When I am adding my email to the form, I am also getting this error:
The specified value "MYEMAILADDRESS" is not a valid email address.
Here is my set up
routes.rb
resources :shop
shop_controller
class ShopController < ApplicationController
def index
#products = Product.all
end
def show
#product = Product.find(params[:id])
end
def new
end
# the create happens in the show action
def create
#product = Product.find(params[:id])
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #product.price * 100,
:description => #product.description,
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
show.html.erb (where the form is rendered to pay)
<div class='shop-show'>
<div class="container">
<div class="row text-center">
<div class="col-lg-12 col-xs-12">
<h2><%= #product.name %></h2>
<hr class="generic">
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="white_panel">
<%= form_for #product, url: url_for(controller: 'shop', action: 'create' ) do %>
<% if flash[:error].present? %>
<div id="error_explanation">
<p><%= flash[:error] %></p>
</div>
<% end %>
<script src="http://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="<%= #product.description %>"
data-amount="<%= #product.price * 100 %>"
data-locale="auto"
data-shipping-address=true>
</script>
<% end %>
<img class="img-responsive" width='400' height='250' src="<%= #product.pictures.first.image.url %>">
<h2><%= #product.description %></h2>
</div>
</div>
</div>
</div>
</div>
Has anyone set up this kind of functionality before? This was closely followed using the link provided by stripe: https://stripe.com/docs/checkout/rails. Any help with this set up would be very appreciated. Thanks.
The Checkout ctript tag's URL there needs to be retrieved over HTTPS. Try swapping this:
<script src="http://checkout.stripe.com/checkout.js"
for this:
<script src="https://checkout.stripe.com/checkout.js"

Creating Subscription with stripe

I'm trying to create a subscription package using Stripe..
Here what I have so far
My controller method.
def subscription_one
session[:tab] = "$1.99/Month"
#subscription = Subscription.where(user_id:current_user.id)
end
def create
#subscription = Subscription.new(params[:subscription])
if #subscription.save_with_payment
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
subscription_one.html.erb
<% if #subscription.present? %>
CREDIT CARD DETAILS PRESENT
<% else %>
<form action="/membership/apply" method="POST" id="payment-form">
<article>
<label class="amount"> <span>Amount: $5.00</span> </label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500"></script>
<% end %>
After I give all values in fields that appear, when I submit I get an error
ActionController::InvalidAuthenticityToken in MembershipController#create
Any ideas?
Several issues:
--
Form
The form you've included is hard coded
The problem you have is, as stated by Philidor Green, this form won't have the correct authenticity token provided by Rails. As a rule of thumb, Rails provides helpers for most HTML elements, allowing you to create consistent code for your app:
<%= form_tag path do %>
<% end %>
You should use form_tag for this
--
Subscription
Subscription.new(params[:subscription])
Should be:
def subscribed_one
Subscription.new(subscription_params)
end
private
def subscription_params
params.require(:subscription).permit(:params, :attributes)
end
--
Update
To handle this, I'd do this:
#view
<% if #subscription.present? %>
Credit Card Details Present
<% else %>
<%= form_tag membership_apply_path, id: "payment-form" do %>
<%= content_tag :article do %>
<%= label_tag class: "amount" %>
<%= content_tag :span, "Amount: $5.00" %>
<% end %>
<% submit_tag "Susbcribe" %>
<% end %>
<% end %>
#app/views/layouts/application.html.erb
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500">
</script>
#app/controllers/subscriptions_controller.rb
def subscription_one
session[:tab] = "$1.99/Month"
#subscription = Subscription.where(user_id:current_user.id)
end
def create
#subscription = Subscription.new(params[:subscription])
if #subscription.save_with_payment
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
I found a workaround, maybe to simple to be honest, it's the standard stripe checkout, replacing standart Form element by for_path. It seems working :
<%= form_tag stripe_user_standart_charge_checkout_path do %>
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="..."
data-amount="999"
data-name="Grégoire Mulliez"
data-description="Timee"
data-zip-code="true"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto"
data-currency="eur">
</script>
<% end %>
stripe_user_standart_charge_checkout_path is whatever route you want, don't forget to define it as POST (not get) in your routes.rb
Edit : you can retrieve hour transaction token using this method, also I added some html hidden fields to revrieve and the same time my transaction details , it's working like a charme

Submitting form info to Model from view, then invoking the model to run

I am trying to submit info from a form in my view, that passes the submitted info :hashtag into the model and then runs the model with that info. But it seems thats my model just runs with the words "hashtag" instead of the form info. I believe it is close. I just can't figure out where to go next.
home.html.erb
<div class="row">
<div class="span6 offset2">
<%= form_for :hashtag do |f| %>
<div class="input-prepend input-append">
<span class="add-on swag">#</span>
<%= f.text_field :hashtag , class: "span3 inverse", id:"appendedPrependedInput" %>
<%= f.submit "Swag!", class: "btn btn-inverse" %>
<% end %>
</div>
</div>
<div class="span4">
<div id="hashtags">
<% #random_hashtags.each do |hashtag| %>
<blockquote><%= hashtag.content %></blockquote>
<div class="from">— #<%= hashtag.screen_name %></div>
<% end %>
</div>
</div>
</div>
hashtag.rb
class Hashtag < ActiveRecord::Base
attr_accessible :content, :profile_image, :screen_name, :tweet_date, :tweet_id
def self.pull_hashtag
Twitter.search("%#{hashtag}").results.map do |tweet|
unless exists?(tweet_id: tweet.id)
create!(
tweet_id: tweet.id,
content: tweet.text,
profile_image: tweet.profile_image_url,
screen_name: tweet.from_user,
tweet_date: tweet.created_at
)
end
end
end
end
hashtags_controller
class HashtagsController < ApplicationController
def home
#random_hashtags = Hashtag.order("RANDOM()").limit(4)
end
def create
#hashtag = Hashtag.pull_hashtag(params[:search])
end
end
Updated code that I am currently using now as I was not posting anything to the model
It is going though on submit but it seems nothing from there.
Update 2,
I am trying to post the information to the database, by taking the info from the form, running a Twitter.search on it and creating the results in my database.
Can you try to replace with this?
form_for #hashtag, :url => :action => 'home'
my guess is that the action needs to be specified.

Rails not showing error on form submit

I am working in rails 2, I have a form containing data of two models, In one model I am validating fields and entering error using self.errors.add_to_base , but this is not displaying error on form and submitting that request successfully.
This is my Model validation\
validate :checkPunchingEntries
def checkPunchingEntries
if self.punch_in_time.blank? && self.punch_out_time.blank?
self.errors.add_to_base("Both 'Punch in' and 'Punch out' time can not be blank")
end
end
This is my Form
<% form_tag '/punching_requests/create', :method => :post, :class=>"punching_request_form" do %>
<% #punching_request.errors.full_messages.each do |msg| %>
<p class="error"><%=msg%></p>
<% end %>
<p>
<label>Date </label>
<%= text_field_tag 'date'%> <%= calendar_for("date") %>
</p>
<p>
<label> </label>
<input type="checkbox" onclick="punch_in_toggle()">Punch In</input>
<input type="checkbox" onclick="punch_out_toggle()">Punch Out</input>
</p>
<div id="punch_in">
<p>
<label>Punch In Time </label>
<%= text_field_tag 'punch_in_time'%>
</p>
</div>
<div id="punch_out">
<p>
<label>Punch Out Time </label>
<%= text_field_tag 'punch_out_time'%>
</p>
</div>
<p>
<label>Assign To</label>
<%= select_tag(:approved_by, options_from_collection_for_select(#human_resource_persons, "id", "login")) %>
</p>
<p>
<label>Reason </label>
<%=text_area_tag 'reason'%>
</p>
<p class="actions"><label></label><%= submit_tag 'Save' %></p>
<% end %>
It comes into validation, but error is not shown on validation fails.
Have you tried the IRB console? If not, take a look what is going on there, just to be sure, that #punching_request.errors contains something.
try this
def checkPunchingEntries
if self.punch_in_time.blank? && self.punch_out_time.blank?
errors[:base]<< "Both 'Punch in' and 'Punch out' time can not be blank"
end
end
and use form_for and #punching_request
for example
# in your controller
def new
#punching_request = PunchingRequest.new
end
def create
...
...
end
your form look like in your new.html.erb
form_for(#punching_request)
...
...
end
In this you're generating the form using form_tag and the errors you're expecting would be stored in the form builder,form_for.
Instead of form_tag use form_for(#punching_request). This should do the trick.

Resources