New to stripe, and ruby. Trying to add an application fee to my stripe payment flow. The charges are all making it through to my stripe account, but I can't seem to figure out how/where to add the stripe application fee code.
charges/new.html.erb
<%= form_tag charges_path do %>
<div id="error_explanation">
<% if flash[:error].present? %>
<p><%= flash[:error] %></p>
<% end %>
</div>
<article>
<%= label_tag(:amount, 'Payment Amount:') %>
<%= text_field_tag(:amount) %>
</article>
<article>
<%= hidden_field_tag(:stripeToken) %>
</article>
<button id='donateButton'>Pay</button>
<% end %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<script>
var handler = StripeCheckout.configure({
key: '<%= Rails.configuration.stripe[:publishable_key] %>',
locale: 'auto',
name: 'Payments',
description: 'Pay Someone',
token: function(token) {
$('input#stripeToken').val(token.id);
$('form').submit();
}
});
$('#donateButton').on('click', function(e) {
e.preventDefault();
$('#error_explanation').html('');
var amount = $('input#amount').val();
amount = amount.replace(/\$/g, '').replace(/\,/g, '')
amount = parseFloat(amount);
if (isNaN(amount)) {
$('#error_explanation').html('<p>Please enter a valid amount in CAD ($).</p>');
}
else if (amount < 5.00) {
$('#error_explanation').html('<p>Wage amount must be at least $5.</p>');
}
else {
amount = amount * 100; // Needs to be an integer!
handler.open({
amount: Math.round(amount)
})
}
});
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
</script>
charges_controller.rb
class ChargesController < ApplicationController
def new
end
def create
#amount = params[:amount]
#amount = #amount.gsub('$', '').gsub(',', '')
begin
#amount = Float(#amount).round(2)
rescue
flash[:error] = 'Charge not completed. Please enter a valid amount in USD ($).'
redirect_to new_charge_path
return
end
#amount = (#amount * 100).to_i # Must be an integer!
if #amount < 500
flash[:error] = 'Charge not completed. Donation amount must be at least $5.'
redirect_to new_charge_path
return
end
Stripe::Charge.create(
:amount => #amount,
:currency => 'usd',
:source => params[:stripeToken],
:description => 'Custom donation'
)
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
end
As I've mentioned, the payment flow works fine, Stripe docs says it must be a number, but I would prefer a percentage if that is possible. this is the code given in the examples:
# See your keys here: https://dashboard.stripe.com/account/apikeys
Stripe.api_key = "secret key"
# Get the credit card details submitted by the form
token = params[:stripeToken]
# Create the charge with Stripe
charge = Stripe::Charge.create({
:amount => 1000, # amount in cents
:currency => "cad",
:source => token,
:description => "Example charge",
:application_fee => 123 # amount in cents
},
{:stripe_account => CONNECTED_STRIPE_ACCOUNT_ID}
)
I just dont know where or how to add the application fee code! my payment flow works in that the user can enter their own payment amount, and I cant seem to find any answers here or in the documentation which reflects the code in that form. I'm sure its a simple solution, but I'm very new to working with Stripe.
You can only specify an application_fee when creating a charge with Connect, either directly on a connected account (with the Stripe-Account header) or through the platform (with the destination parameter).
From your code, it doesn't look like you're using Connect at all, so application fees wouldn't apply. Can you clarify what exactly you're trying to do? How should the funds from the charge be split?
Related
I have a store where you can buy digital products via download. Every product purchased (I've tested multiple products) displays the same product's information (title, art_link, and download_url) on the thank you page right after purchase.
What Am I doing wrong here that is preventing it from loading the correct data from the pack just purchased?
I'm using Stripe for payments. Everything else works perfectly, the money goes through, the email is sent and links to the receipt, the UUID works, etc.
UPDATE: I've checked my DB and Everything is saving correctly. The only problem is with the purchases/show view not rendering properly.
purchases/show:
<p><b><%= #pack.title %></b></p>
<%= image_tag("#{#pack.art_link}", :alt => "#{#pack.title} sound library.", :width => 330, :height => 330, class: "img-center img-responsive shade") %>
<p><a class="btn btn-success top-drop" href="<%= #pack.download_url %>" target="_blank">Download Files</a></p>
purchases_controller:
def show
#purchase = Purchase.find_by_uuid(params[:id])
#pack = Pack.find(#purchase.product_id)
set_meta_tags noindex: true
end
Purchase model:
attr_accessor :download_token
after_create :email_purchaser
def to_param
uuid
end
def email_purchaser
PurchaseMailer.purchase_receipt(self).deliver
end
def Purchase.new_token
SecureRandom.urlsafe_base64
end
def create_download
self.download_token = Purchase.email.new_token
update_attribute(:download, Purchase.email(download_token))
update_attribute(:download_sent_at, Time.zone.now)
end
charges_controller:
def create
pack = Pack.find(params[:product_id])
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken],
)
# Amount in cents
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => pack.price_in_cents,
:description => 'Rails Stripe customer',
:currency => 'usd',
)
purchase = Purchase.create(
email: params[:stripeEmail],
card: params[:stripeToken],
amount: pack.price_in_cents,
description: charge.description,
currency: charge.currency,
customer_id: customer.id,
product_id: pack.id,
uuid: SecureRandom.uuid,
)
redirect_to purchase
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
Thank you very much, this really has me stuck.
Routes.rb:
resources :packs, :path => 'products'
resources :charges
resources :purchases, only: [:show]
The problem was solved on a chat.
In routes.rb, there were following lines:
get 'purchase' => 'purchases#show', as: 'purchase'
...
resources :purchases, only: [:show]
So when OP called: redirect_to purchase the URL was:
http://localhost:3000/purchase.4c77a556-299e-4611-b683-3ff6eb672738
From that, the params[:id] was nil. In DB, there were 4 purchases with UUID equal nil, and the first one was always returned (because find_by returns the first matched record).
def create_charge
#amount = 500
customer = Stripe::Customer.create(email: params[:email])
pay = Stripe::Charge.create(
:amount => params[:amount],
:currency =>params[:currency],
# :source=>params[:token],
:customer=>customer.id, # obtained with Stripe.js
:description => "Charge for ")
send_json_response("Payment","success",{:pay=>pay})
end
Am trying to create a customer and charge that customer using Rails and Stripe. The customer is getting created in Stripe, but I keep getting the error Cannot charge a customer that has no active card when trying to do the charge
if you are taking info of card on this time ... first check card is valid or not
begin
#token = Stripe::Token.create(
:card => {
:number => params[:card][:card_number],
:exp_month => params[:card][:exp_month],
:exp_year => params[:card][:exp_year],
:cvc => params[:card][:ccv]
},
)
rescue Stripe::CardError, Stripe::InvalidRequestError => e
flash[:error] = e.message and return
rescue
flash[:notice] = 'Something went wrong! Try Again' and return
end
if customer is connected to your website
run webhooks of stripe to check if customer has valid card if not then take that customer to update card page ... to update its card before any purchase
check event type where ( "type": "customer.source.updated")
https://stripe.com/docs/api#event_types
on update card try to check again card is valid or not
I'm using stripe checkout in a Rails 4x app. My goal is to provide monthly subscriptions. I'm receiving the following.
Stripe::InvalidRequestError Cannot use stripeToken more than once. This happens when create_stripe_subscription is called in subscriptions_controller#create.
In spite of this error message, I have customers who have made charges that appear in my stripe dashboard.
I'd like to learn where I'm duplicating this one-time-usage token and understand what stripe is requiring for this subscription.
Here are associated files & images to demonstrate what my implementation efforts are looking like so far.
initializers/stripe.rb:
Rails.configuration.stripe = {
publishable_key: ENV["STRIPE_PUBLISHABLE_KEY"],
secret_key: ENV["STRIPE_SECRET_KEY"]
}
Stripe.api_key = Rails.configuration.stripe[:secret_key]
subscriptions/new (the "small" plan's stripe checkout button)
<script src="https://checkout.stripe.com/checkout.js"
class="stripe-button",
data-key="<%= ENV["STRIPE_PUBLISHABLE_KEY"] %>",
data-email="<%= current_employee.email %>",
data-image="app/assets/images/mascot_favicon.ico",
data-name="Small Group Home",
data-description="Monthly subcription plan",
data-amount="<%= #small_plan.amount %>",
data-id="<%= #small_plan.id %>",
data-label="Subscribe!">
</script>
subscriptions_controller.rb
def create
create_stripe_subscription
if create_stripe_subscription.valid?
AdminMailer.welcome_email(#admin).deliver_now
flash[:success] = "#{ #admin.full_name.pluralize } created!"
redirect_to root_path
else
flash.now[:notice] = "There was a problem with the form"
render :new
end
end
.
.
.
def create_stripe_subscription
plan_id = params[:plan_id]
plan = Stripe::Plan.retrieve(plan_id)
token = params[:stripeToken]
email = params[:stripeEmail]
customer = Stripe::Customer.create(
source: token,
email: email,
plan: plan
)
subscription = Subscription.new
subscription.stripe_card_token = customer.id
same_customer = Stripe::Customer.retrieve(subscription.stripe_card_token)
same_customer.subscriptions.create(plan: params[:plan_id])
end
stipe dash
I figured it out by handling the Stripe::InvalidRequestError in the create_stripe_subscription method like so:
subscriptions_controller.rb
def create_stripe_subscription
.
.
.
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error: #{e.message}"
end
Which led me to a noMethodError from my app. Then error came from this line in my subscriptions_controller's create method.
if create_stripe_subscription.valid?
Removing valid? allowed the create method to finish up, sending the email and redirecting as it should.
I've been trying to convert the following from html.erb to html.haml, but things aren't rendering 100% correctly. Specifically I'm wondering how to correctly write the bit of code within the script tags in Haml.
html.erb:
<%= form_tag charges_path do %>
<h4>So what comes with being a Blocipedia premium member? </h4>
<p>The ability to create your very OWN private wikis of course!</p>
<script class='stripe-button' src="https://checkout.stripe.com/checkout.js" data-key="<%= #stripe_btn_data[:key] %>" data-amount=<%= #stripe_btn_data[:amount] %> data-description="<%= #stripe_btn_data[:description] %>" ></script>
<% end %>
html.haml:
= form_tag charges_path do
%h4 So what comes with being a Blocipedia premium member?
%p The ability to create your very OWN private wikis of course!
%script.stripe-button{"data-key" => #stripe_btn_data[:key], :src => "https://checkout.stripe.com/checkout.js", "data_amount" => #stripe_btn_data[:amount], "data_description" => #stripe_btn_data[:description]}
Before I tried to rewrite my code in Haml, my original html.erb file rendered like so below.
Before Haml (The way my page SHOULD render):
Yet after trying to change to Haml, I was not 100% successful in getting the page to render in exactly the same way
After Haml (notice the data-amount ($15.00) and the data-discription (BigMoney Membership) aren't being displayed)
What is the correct Haml syntax to render this page properly?
Update
I'm trying to grab the data-amount and description from my charges_controller.rb
charges_controller.rb:
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[:notice] = "Thanks for all the money, #{current_user.email}! You now have a premium Blocipedia account! Feel free to pay me again."
current_user.update_attribute(:role, "premium")
redirect_to root_path # 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
def destroy
if current_user.update_attributes(role: "standard")
flash[:notice] = "You now have a standard Blocipedia account. Feel free to upgrade back to premium at anytime!"
redirect_to root_path
else
flash[:error] = "There was an error downgrading your account. Please contact technical support."
redirect_to edit_user_registration_path
end
end
end
amount.rb:
class Amount
def self.default
15_00
end
end
To achieve the same HTML output of ERB using HAML
= form_tag charges_path do
%h4 So what comes with being a Blocipedia premium member?
%p The ability to create your very OWN private wikis of course!
%script.stripe-button{data: {key: #stripe_btn_data[:key], amount: #stripe_btn_data[:amount], description: #stripe_btn_data[:description]}, src: "https://checkout.stripe.com/checkout.js"}
I'm using CareerFoundry's tutorial on setting up Stripe Checkout with Rails. I'm getting an error on form submission that the public API is incorrect. I think the problem is in the initializer file below, but it could be something else.
Config/initializers/stripe.rb
if Rails.env.production?
Rails.configuration.stripe = {
publishable_key: ENV[ 'STRIPE_PUBLISHABLE_KEY' ],
secret_key: ENV[ 'STRIPE_SECRET_KEY' ]
}
else
Rails.configuration.stripe = {
publishable_key: 'pk_test_UQ2EqhNNQRrDkDouuZ1xgpS5', #Both test keys are fakes in case you're wondering
secret_key: 'sk_test_hkiYUThcriCTBfHuUSXpUP7n'
}
end
Payments Controller
class PaymentsController < ApplicationController
def create #You want might to make actions more specific.
token = params[:stripeToken] #The token when the form is posted includes the stripe token in the url.
# Create the charge in stripes servers. This is what commits the transaction.
begin
charge = Stripe::Charge.create(
:amount => 200,
:currency => "usd",
:source => token,
:description => params[:stripeEmail]
)
rescue Stripe::CardError => e
#The card was decline because of number/ccv error, expired error, bank decline, or zip error
body = e.json_body
err = body[:error]
flash[:error] = "There was an error in processing your card: #{err[:message]}"
end
respond_to do |format|
format.html { redirect_to "/confirmation" }
#format.html { redirect_to "/purchase", notice: "Purchase was successfully completed. We'll be in contact shortly!" }
end
end
end
Views/Shared/_stripe_checkout_button.html.erb
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-image="/assets/square-image.png"
data-name="Achieve More"
data-description="1 Month ($800)"
data-amount="2000">
</script>
Views/payments.html.erb
<%= form_tag "/payments" do %>
<%= render partial: "shared/stripe_checkout_button" %>
<% end %>
So the CareerFoundry tutorial didn't have anything about setting the keys. The stripe demo does. This line:
heroku config:set PUBLISHABLE_KEY=pk_test_UQ2EqhNNQRrDkD5V0Z1xgpS5 SECRET_KEY=sk_test_hkiYUTQzHiCTBfHuUSXpUP7n
sets the keys for the initializer. Those were missing, causing the error.