Reputation: 1560
I have a form with radio buttons to select an option for the amount to donate.
That looks like this:
<tr>
<td><input type="radio" name="amount" value="10"><span>$10</span></td>
<td><input class="awk" type="radio" name="amount" value="25"><span>$25</span></td>
</tr>
<tr>
<td><input type="radio" name="amount" value="50"><span>$50</span></td>
<td><input type="radio" name="amount" value="100"><span>$100</span></td>
</tr>
There's a pay button, which opens stripes payment gateway.
for the form I have is this:
<%= form_tag charges_path, id: 'chargeForm' do %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<%= hidden_field_tag 'stripeToken' %>
<%= hidden_field_tag 'stripeEmail' %>
<button id="customButton" class="btn btn-large btn-primary">Buy Now</button>
<script>
var handler = StripeCheckout.configure({
key: 'foo',
image: '/assets/my_logo.png',
token: function(token, args) {
document.getElementById("stripeToken").value = token.id;
document.getElementById("stripeEmail").value = token.email;
document.getElementById("chargeForm").submit();
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'My Company',
description: 'Product ($60.00)',
amount: (100 * $('input[name=amount]:checked', '#stripe_donate').val()),
shippingAddress: false
});
e.preventDefault();
});
</script>
<% end %>
This loads the stripe modal correctly displaying the correct amount on the pay button, but how do I tell RAILS how much to charge the customer? Stripe is charging $5.00 no matter what because of the rails controller code:
class ChargesController < ApplicationController
def new
end
def create
# Amount in cents
@amount = 500
customer = Stripe::Customer.create(
:email => '[email protected]',
: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
end
So How do I tell rails in the controller that the @amount needs to be set to a value received from the page? Do I just skip the rails route altogether and do this using pure JS?
Upvotes: 0
Views: 776
Reputation: 6682
First, I moved the donation amounts into a constant and added support for an :amount
attribute (assuming Rails 3.x and a model named Charge
). This allows you to add or remove dollar amounts with ease, and submit the selected dollar amount with the form:
# /app/models/charge.rb
DONATION_DOLLAR_AMOUNTS = [10, 25, 50, 100]
attr_accessor :amount
In the view, move radio buttons inside the form and use proper labels. We use the constant to generate a button for each dollar amount. (I removed the table structure because a form cannot cross table rows).
<%= form_tag charges_path, id: 'chargeForm' do %>
<!-- generate four radio buttons with labels (TODO: move this into a helper) -->
<% Charge::DONATION_DOLLAR_AMOUNTS.each do |amt| %>
<%= radio_button_tag "amount", amt %>
<%= label_tag "amount_#{amt}", number_to_currency(amt, precision: 0) %>
<script src="https://checkout.stripe.com/checkout.js"></script>
<%= hidden_field_tag 'stripeToken' %>
<%= hidden_field_tag 'stripeEmail' %>
<button id="customButton" class="btn btn-large btn-primary">Buy Now</button>
<!-- ... -->
Pick up the value in the controller:
def create
# Use dollar amount in param or 5 if none, then convert to cents
@amount = (params[:amount] || 5) * 100
# ...
Upvotes: 1
Reputation: 669
You should put the radio buttons inside of the form (there should only be one form) and then get that value on the controller (you might want to set the values to cents, or otherwise convert it to cents in the controller).
Upvotes: 0
Reputation: 16373
Do an ajax submission to the rails controller with the amount as a parameter, along with the stripe token:
(jquery)
var data = {
'amount': $('input[name="amount"]').val(),
'stripeToken': stripeToken //what you got from checkout.js
}
$.post( "/charges", function( data ) {
console.log('Sent charge to controller!')
});
(rails)
def create
# Amount in cents
@amount = params[:amount]
Alternatively, put everything in a form and POST to the /charges url, like you're presumably already doing to send the stripeToken.
Upvotes: 0