Building an application in rails that uses stripe for its payment/checkout system. I have the charges controller, new.html.erb and all the necessary gems in place but for some reason whenever I use my credit card to test stripe with a real payment (the charge is only $2 so it doesn't hurt to test) it appears in my logs as a v1/token rather than a v1/charge and does not appear in the payments section. I have researched extensively the conversion from token to charge and have found multiple answers pointing to the same solution (creating a begin method that turns tokens into charges which I have) but when implementing it doesn't work for me. this is my current charges controller:
require "stripe"
class ChargesController < ApplicationController
def new
# this will remain empty unless you need to set some instance variables to pass on
end
def create
# Amount in cents
#amount = 200
# Set your secret key: remember to change this to your live secret key in production
# See your keys here https://dashboard.stripe.com/account/apikeys
Stripe.api_key = "pk_live_z....." //taken out for security reasons
# Get the credit card details submitted by the form
token = params[:stripeToken]
# Create the charge on Stripe's servers - this will charge the user's card
begin
charge = Stripe::Charge.create(
:amount => #amount, # amount in cents, again
:currency => "usd",
:source => token,
:description => "Example charge"
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
end
your create method is not being called which executes the logic of payment.
Related
I have a rails app where Stripe is set up similar to this documentation. When I hit the "Pay With Card" button and enter the test card information it says it's successful, then gives me an error message saying:
No route matches [POST] "/charges/new"
Even though my routes are like this:
resources :charges
get 'charges/shipping'
get 'charges/address'
post 'charges/update_order'
My charges_controller reads like this:
class ChargesController < ApplicationController
...
def new
#order = current_order
end
def create
# Amount in cents
#amount = current_order.total * 100
#user = current_user
#order = current_order
if #user.stripe_customer_id
customer = #user.stripe_customer_id
else
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
#user.update_attributes(stripe_customer_id: customer.id)
end
#order.update_attributes(order_status_id: 2)
#order.update_attributes(date_placed: DateTime.now)
# OrderMailer.order_placed(#order.user, #order).deliver_now
session[:order_id] = nil
charge = Stripe::Charge.create(
:customer => #user.stripe_customer_id,
:amount => #amount.to_i,
:description => 'Rails Stripe customer',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
private
def order_params
params.permit(:subtotal, :tax, :shipping, :total, :order_status_id, :user_id, :date_placed, :shipping_choice)
end
end
If I manually insert a post "charges/new" into the routes.rb it says it's successful, but it redirects to the same page (indicating a Stripe::CardError) and no charge registers in the stripe dashboard.
Can anyone see where I'm going wrong?
It looks like you're not permitting the 'stripeToken' parameter in your order_params. Because of camel-case that might be a little fiddly, but make sure you're allowing that param with something like:
params.permit( :"stripeToken" …
Without this, that parameter is null, and would give you a Stripe failure.
Without seeing your client side code, I can't be sure - but it sounds like your client side code is trying to POST to /charges/new - which doesn't exist - so it's failing. I'd suggest you update your client side code to POST to the route you want to have handle that, and then continue debugging from there.
The problem is this part here in your controller:
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
You should remove redirect_to new_charge_path, and simply just let Stripe render the error message. No need to redirect upon error. Stripe takes care of the error-handling for you (which is one of the things making Stripe great).
Currently, your redirect_to is being treated as the path after each successful purchase. Not just on errors.
Update
Upon further looking at your code. You don´t seem to actually have a redirect_to after each successful purchase. So regardless, you should remove the redirect_to new_charge_path because it´s currently arbitrary to => e. It might look like it has something to do with the Error handiling, cause it's below that block, but in fact it doesn't. You should instead add redirect_to successful_path or render :success (for instance) right above the rescue Stripe::CardError =>. And then let Stripe handle (or rescue) failed attempts to make a purchase, as explained before.
Try to restart your server to reload the routes. Run rake routes | grep charges to verify that you see POST /charges/new.
Wait, I know why. You are supposed to GET /charges/new and POST to /charges. Show us your view code, specifically the form submission URL address.
See http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions
In the end I had to change the code on the form to charge_path instead of new_charge_path so it would hit the create action. Even though this was different from the Stripe documentation it ended up working.
Trying to implement Stripe into my app, but my understanding of Ruby/Rails' syntax is, while functional, still very basic. How should I express a default amount? I'm being prompted to "create a Amount class and its default class method, which should return the number you wish to charge, in pennies. One such value might be 15_00, for fifteen dollars." Thanks in advance for the help!
class ChargesController < ApplicationController
def create
# Creates a Stripe Customer object, for associating
# with the charge
customer = Stripe::Customer.create(
email: current_user.email,
card: params[:stripeToken]
)
# Where the real magic happens
charge = Stripe::Charge.create(
customer: customer.id, # Note -- this is NOT the user_id in your app
amount: Amount.default,
description: "BigMoney Membership - #{current_user.email}",
currency: 'usd'
)
flash[:success] = "Thanks for all the money, #{current_user.email}! Feel free to pay me again."
redirect_to user_path(current_user) # or wherever
# Stripe will send back CardErrors, with friendly messages
# when something goes wrong.
# This `rescue block` catches and displays those errors.
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
def new
#stripe_btn_data = {
key: "#{ Rails.configuration.stripe[:publishable_key] }",
description: "BigMoney Membership - #{current_user.name}",
amount: Amount.default
}
end
end
am currently working on integrating my sample site with Authorize.NET.
So I created a Sandbox account in Authorize.NET.
Using this test account, I am testing DPM and using Relay Response URL.
I have Public IP
I am setting the x_relay_response="TRUE"; x_relay_url="http://182.180.157.5:3000/payments/relay_response";
Controller
class PaymentsController < ApplicationController
layout 'authorize_net'
helper :authorize_net
protect_from_forgery :except => :relay_response
# GET
# Displays a payment form.
def payment
#amount = 125.00
#sim_transaction = AuthorizeNet::SIM::Transaction.new(AUTHORIZE_NET_CONFIG['api_login_id'], AUTHORIZE_NET_CONFIG['api_transaction_key'], #amount, :relay_response => true, :relay_url => "http://182.180.157.5:3000/payments/relay_response")
end
# POST
# Returns relay response when Authorize.Net POSTs to us.
def relay_response
puts "In Relay Response"
puts "Params: #{params}"
sim_response = AuthorizeNet::SIM::Response.new(params)
if sim_response.success?(AUTHORIZE_NET_CONFIG['api_login_id'], AUTHORIZE_NET_CONFIG['merchant_hash_value'])
render :text => sim_response.direct_post_reply("http://182.180.157.5:3000/payments/receipt", :include => true)
else
render
end
end
# GET
# Displays a receipt.
def receipt
#auth_code = params[:x_auth_code]
end
end
Getting This Error
An error occurred while trying to report this transaction to the merchant. An e-mail has been sent to the merchant informing them of the error. The following is the result of the attempt to charge your credit card.
This transaction has been approved.
It is advisable for you to contact the merchant to verify that you will receive the product or service.
Any Solution For This
Context:
I am using Stripe checkout to accept one-time payment in rails.
I have a charges controller as shown below.
I was initially using stripe webhook to listen to charge.succeeded, but running into some issues due to the async nature of webhooks.
My I have moved the business logic to the controller.
If the customer charge is a success, then I save the customer and some other details to the db.
My question:
Is this check enough to ensure that a charge is successful ?
if charge["paid"] == true
The Stripe documentation for Stripe::Charge.create states, "
Returns a charge object if the charge succeeded. Raises an error if something goes wrong. A common source of error is an invalid or expired card, or a valid card with insufficient available balance."
My ChargesController:
class ChargesController < ApplicationController
def new
end
def create
# Amount in cents
#amount = 100
temp_job_id = cookies[:temp_job_id]
customer_email = TempJobPost.find_by(id: temp_job_id).company[:email]
customer = Stripe::Customer.create(
:email => customer_email,
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Rails Stripe customer',
:currency => 'usd',
:metadata => {"job_id"=> temp_job_id}
)
# TODO: charge.paid or charge["paid"]
if charge["paid"] == true
#Save customer to the db
end
# need to test this and refactor this using begin-->rescue--->end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end
end
Yes, that's all you need to do. If the charge succeeded, Stripe will return a Charge object, and you can check its paid parameter. If the charge failed, we'd throw an exception.
Cheers,
Larry
PS I work on Support at Stripe.
I have a requirement where i have list of products and each product belongs to various seller and now the user can sign in to the application and buy the product and amount will be transferred to the corresponding seller stripe account. I am struggling with how to proceed with this.
I so far have allowed the seller to signup and connect his stripe account if he has already one or signup and get the code back to the app but i also wanted to know how to get the access token by posting the code that is received in rails and i wanted to know how the user can send the money through card to the corresponding seller.
Please help me
This is speculative (I don't know if you can do this with the current Stripe API):
Can't you assign the seller's stripe access tokens to the Stripe instance?
It seems the Stripe credentials are set in an initializer, which generally means they can't be changed; although I'd hazard a guess you can do by either calling a new instance of the Stripe object, or dynamically setting the seller details:
def create
# Amount in cents
#amount = 500
seller = User.find_by id: params[:product_id]
Stripe.api_key = seller.stripe_api
customer = Stripe::Customer.create(
:email => 'example#stripe.com',
:card => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #amount,
:description => 'Rails Stripe customer',
:currency => 'usd'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to charges_path
end