Adding a subscription option with Stripe

Hi Alex, I've looked at the Stripe documentation and some other online tutorials of setting up a subscription model like you have here on BaseRails. I've tried to follow along with those, but just can't seem to get things to work. Is there a good tutorial you know about, or can you spare a minute to give me a rough outline of what needs to be done? Thanks!

Posted over 5 years ago by Nate
Posted over 5 years ago by Nate

I've gotten this working in part...

I'm using the embedable checkout form (javascript) provided by Stripe. I have a monthly plan and a yearly plan, and I also want to give people the option of buying lifetime access with a one off payment.

What's working: Someone can purchase a subscription. The app tracks that they are a subscriber and prevents them from accessing the payment form again.

What's left to do: I need to give them some way to cancel their payment, and take away access to the site. I also would like to offer coupons.

Thoughts: I think the javascript form is probably too limiting. I could do it, but I would need to have new devise users have access blocked until they paid. I want users to have a trial period as well, but it starts to get too complicated with all the forms.

What would you suggest? I appreciate the help.

0
Posted over 5 years ago by Alex Yang

It sounds like you want to use a lot of different Stripe features (subscription, one-time payments, trials, coupons). I suggest getting a simpler setup to work first (e.g. just subscription) and then layering each additional feature one-by-one.

Start by getting subscriptions and cancellations (and subscription modifications) working. For cancellations, you'll basically need a button that routes to a 'cancel' action. This 'cancel' action needs to be defined in your controller file. It should look similar to this:

def cancel
@customer = Stripe::Customer.retrieve(current_user.customer_id)
@customer.subscriptions.first.delete()
current_user.active = false
end

In the code above, each User has a 'customer_id' field that stores their Stripe customer ID, which is used to look up the customer info using the Stripe API. We're then deleting that user's first subscription (assuming that your users only have at most one active subscription). Finally, Users have an 'active' field that's used to track whether they should have access, so we need to set that to false.

Try getting this whole subscription side working first - hope that helps!

0
Posted over 5 years ago by Nate

That helps a lot!

I've got it working more or less. For example, the cancel subscription button works. But there is a problem.

When a user chooses a monthly subscription, they're also charged for the one time price. Here's a gist of what I've done. I'm guessing I've got to separate these somehow, but I'm not getting how to do that...

https://gist.github.com/natanio/299b9199d6c3e12c37c6

Also, I've got buttons for the JS form all on one page. The monthly subscription works fine, but the yearly gives the user access without charging their card. Is it not possible to have those buttons on one page? Thanks a lot!

0
Posted over 5 years ago by Alex Yang

Right now, whenever the subscription form is submitted, your app will perform everything under the 'create' action: creating a Stripe customer on a subscription plan in addition to submitting a one-time charge of $97. Instead, you need to make sure that users that choose a monthly subscription are signed up on a subscription plan while users that choose a one-time payment are only charged a one-time fee.

To do that, your payment form needs to have a switch (e.g. a radio button or dropdown menu) that indicates which payment option the user is choosing, whether it's a one-time fee, monthly subscription, or yearly subscription. Your controller can then use that switch to decide what to do. Think about using an 'if' statement like the following:

if params[:payment_option] == "monthly"

As for your question about multiple buttons on the same page, it is possible to do this - you just need to make sure your JavaScript code is right :-). The most important thing is to ensure that you're using the right selectors, which let you decide when to take action (e.g. when a specific radio button is clicked or when a certain form is submitted).

0
Posted over 5 years ago by Nate

Alex, miraculously I got all of this to work. It required scouring the web for how to make the proper javascript code, but it's all working how I want to for now :)

Thanks a lot for your help!

0
Posted over 5 years ago by Alex Yang

That's awesome, Nate! Do you mind posting how you solved it so that others may benefit as well?

0
Posted over 5 years ago by Nate

Sure thing.

I had to change the form by giving it an id, and then add two more hidden fields. This is to get the custom javascript working for the Stripe button. It looks like this:

<%= form_tag charges_path, id: 'idForm' do |form| %>
<%= hidden_field_tag 'stripeToken' %>
<%= hidden_field_tag 'stripeEmail' %>
<%= hidden_field :charges, :plan_id, value: "plan_id" %>

Next, you add the html for the custom button:

<button id="monthlyButton" class="btn btn-large btn-success">Buy Now</button>

Finally, add the custom javascript under the button in each form, changing the appropriate ids and giving each handler a different name. This is what I finally got to work:

<script>
var formHandler = StripeCheckout.configure({
key: '<%= ENV["STRIPE_PUBLIC_KEY"] %>',
image: 'src',
token: function(response) {
var tokenInput = $("<input type=hidden name=stripeToken />").val(response.id);
var emailInput = $("<input type=hidden name=stripeEmail />").val(response.email);
$("form#idForm").append(tokenInput).append(emailInput).submit();
}
});

document.getElementById('formButton').addEventListener('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'Business Name',
description: 'Plan',
amount: 9*100,
});
e.preventDefault();
});
</script>

Hope that helps someone else!

0
Posted over 5 years ago by Alex Yang

Thanks Nate!

0
Posted over 5 years ago by Nate

Cool! Glad to know!

I've set the controller up to work, but for some reason the plan_type parameter is not getting passed in. Here's the form code. I think I'm missing something Stripe needs, but can't find what that is...

<%= form_tag charges_path do %>
<%= hidden_field_tag :charges, :plan_type, value: "ts_monthly" %>
..
..
<% end %>

0
Posted over 5 years ago by Alex Yang

Happy to help, Nate. It's not simple to set up subscriptions, so it might be easier if you can tell me what you've tried so far and I can guide you from there. Also, please let me know whether you plan to have all your users on a subscription plan. If so, you'll be able to merge the payment form with the user signup form.

0