Ask A Question

Notifications

You’re not receiving notifications from this thread.

Subscriptions with Stripe Discussion

Discussion for Subscriptions with Stripe

Hi, thanks for this tutorial. I am reading that now stripe has deprecated the custom form method and is moving to the elements UI method (https://github.com/mage2pro.... Following the elements ui method I managed to get the payments to go through by copying in the examples on the stripe site and using the same controller format as you used. However, I'm having problems retrieving the card info in the way you did that was previously different with the custom form method. Any idea how to do that with the element ui method they are moving to? Thanks

This is my subscribe new view, I kept the javascript in the view.

<h1>Subscribe!</h1>

<%= form_tag subscription_path, id: "payment-form" do%>
<form action="/subscription" method="post" id="payment-form">
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element">

</div>

<div id="card-errors" role="alert"></div>
</div>

<button>Submit Payment</button>
</form>
<% end %>

<script>

//var stripe = Stripe('#############');
var stripe = Stripe($("meta[name='stripe-key']").attr("content"));
var elements = stripe.elements();

// Custom styling can be passed to options when creating an Element.
var style = {
base: {
// Add your base input styles here. For example:
fontSize: '16px',
lineHeight: '24px'
}
};

// Create an instance of the card Element
var card = elements.create('card', {style: style});

// Add an instance of the card Element into the `card-element` <div>
card.mount('#card-element');

card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}

});

// Create a token or display an error when the form is submitted.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();

stripe.createToken(card).then(function(result) {

if (result.error) {
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server
stripeTokenHandler(result.token);

}
});
});

function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server

var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
form.submit();

}

</script>

Reply

I think the way to do it is with the new elements method (as opposed to the customer form method) is to use the customer id to get the "default source" object to retrieve the card. And then from there to retrieve everything from the card object that's returned but I'm just not sure about the syntax.

Reply

For some reason my Stripe data is not being saved to my user? Below is screenshots.
I tried to permit the stripe attributes from my user table but no luck. When I go into my stripe dashboard all the data from the user is there but the data is not saved to database.

Also when I ran the code below. When the user paid for their subscription and redirects me. For some reason I still get the results of "My BAD". I do not have any attr_accessor anywhere as well.

<% if current_user_subscribed? %>
  OUR SECRET VIDEO
  <% else %>
  MY BAD
  <% end %>


    subscriptions_controller.rb

    class SubscriptionsController < ApplicationController
    before_action :authenticate_user!, except: [:new]
    before_action :redirect_to_signup, only: [:new]

  def show

  end

  def new

  end

  def create
     Stripe.api_key = Rails.application.secrets.stripe_secret_key
      token = params[:stripeToken]

      customer = if current_user.stripe_id?
                 Stripe::Customer.retrieve(current_user.stripe_id)
               else
                 Stripe::Customer.create(email: current_user.email, :source => "tok_amex")
               end

      subscription = customer.subscriptions.create(
      plan: "plan_DgFuhaPFeIbeT3"
      )

      current_user.update(
      card_last4: params[:card_last4],
      card_exp_month: params[:card_exp_month],
      card_exp_year: params[:card_exp_year],
      card_type: params[:card_brand]
    )

      redirect_to root_path, notice: "You already a premium member!"
  end

  def destroy

  end

  private

  def redirect_to_signup
    if !user_signed_in?
        session["user_return_to"] = new_subscription_path
        redirect_to new_user_registration_path
    end
  end

end


RAILS CONSOLE

User Load (0.5ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1  [["LIMIT", 1]]
 => #<User id: 7, email: "ddd@gmail.com", first_name: nil, last_name: nil, country: nil, state: nil, city: nil, ph
one: nil, created_at: "2018-09-27 20:20:49", updated_at: "2018-09-27 20:20:49", subscribed: nil, stripe_id: nil, s
tripe_subscription_id: nil, card_last4: nil, card_exp_month: nil, card_exp_year: nil, card_type: nil>
2.4.1 :002 >

Reply

Hey there!
I'm currently asking myself, how you would implement a plan dynamically? You would need to create a Plan with plan = Stripe::Plan.create(plan: project.name) and so on. Afterwards you would call subscriptions on the plan, like plan.subscriptions.create ?

It would be nice to get more detailed information.

Reply

Pretty much! You would create the plan in stripe (it requires it to be attached to a product these days). Once you had the Stripe plan ID, you can use that to create a subscription:

customer.subscriptions.create(items: [{ plan: 'plan-id' }])

or

Stripe::Subscription.create({
  customer: 'customer-id',
  items: [{ plan: 'plan-id' }],
})
Reply

Hello,
Would it be possible to add a record to the CHARGE DB for the initial subscription via the subscriptions controller?

Reply

Hi Chris,
I'm sorry if I missed this but with a monthly subscription, will Stripe send off an email notifying the customer that a payment is due, or is it up to us to set that up?

Thanks!

Jim

Reply

That's up to you I'm pretty sure. They do allow you to configure their emails for various things like failed payments though. You can find all those email options in the Settings tab on Stripe.

Reply

Thanks Chris!

Reply

Is this episode still up to date with how stripe works? It doesn't seem the same as the docs:
https://stripe.com/docs/billing/subscriptions/fixed-price

Reply

I've turned it into a separate course since Stripe changes so much and it's hard to maintain these videos. https://courses.gorails.com/payments-with-rails-master-class

Reply

please update the course with the new stripe version.

Reply

Hi Chris,
Just joined GoRails to access the pro videos! Would it be possible to update the Stripe courses with the latest Stripe API? I followed the video from 2015 but it doesn’t seem to work. I’m trying to do something similar: user subscribes to plan (multiple plans to choose from) and should be able to cancel their plan or modify it. Would really love to see such an episode.
Thanks!

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,733+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.