Rails Stripe Subscriptions Part 2 - Stripe Subscriptions with Stripe Connect

Once you have set up Stripe Connect and Oauth Workflow working in your application, you have many options to choose from. The following post will go over how to create subscriptions, plans, and customers on your user's connected stripe accounts and efficient ways to organize this logic.

Step 2: In my application I use "Enrollments" to control subscriptions to different courses and users. Enrollments in this application belong_to both the course and user, which offer an easy middle ground to control subscriptions and access to courses. We will start in the enrollment model and pass variables from the controller.

1. Creating A Plan: A plan is a blueprint object for subscriptions. When you subscribe in Stripe, it will use the plan details to create a subscription object. In my Enrollment model I will create one method dealing with plan creation:

def self.create_stripe_plan(user, course, enroll, amount)
  plan = Stripe::Plan.create({
    :amount => amount,
    :interval => 'month',
    :name => course.title,
    :currency => 'usd',
    :id => course.title.to_s + course.id.to_s},
    {:stripe_account => course.user.uid}
  enroll.update(plan_id: plan.id)

2. In plan creation you'll want to pass the current_user(user), current_course(course), current_enrollment(enroll), and any other arguments from the object you want to create a plan for. For those who are unfamiliar: current_user is a devise method and not available in the model, which is why I'm passing it through an argument. current_course and current_enrollment are custom private methods created in the controller:

  def current_course
    @current_course ||= Course.find(params[:course_id])

  def current_enrollment
    @current_enrollment ||= Enrollment.find_by(user_id: current_user.id, course_id: current_course.id)

3. In :stripe_account within plan creation, I'm using the connected users Stripe ID(from part 1) so they can get paid when someone subscribes to them. Why is this important? Because, in order to charge a subscription_fee_percent, your user's connected Stripe account needs to have a plan object, customer object, and subscription object created on their account.

4. A few other important things to take notice of are:

1. Make sure the plan ID is unique. You do not want a duplicate plan floating around, or a possible error(a plan exists already).

2. In the beginning of plan creation I set it to a variable so I can save the plan.id to the enrollment I just created. You want to save this ID later for subscription creation and possible deletion.

5. Now that you have plan creation, you can call this method in the controller:

Enrollment.create_stripe_plan(current_user, current_course, current_enrollment, amount)

6. Creating A Customer: After plan creation, you will want to create a customer by following most of the previous steps:

def self.create_stripe_customer(user, course, token)
  customer = Stripe::Customer.create({
    :email => user.email,
    :source => token,
    :description => "Qelody Subscriber for #{course.title}"},
    {:stripe_account => course.user.uid}
  user.update(customer_id: customer.id)

7. A few things to take note of in customer creation:

1. The token from checkout is being passed from the controller to the model via an argument in this method.

2. Make sure to save the customer ID to the current_user for future purchases/subscriptions.

3. Once again, in :stripe_account, I'm using the connected users Stripe account ID to create a customer for them on their Stripe account. Make sure you only create a customer on a current_user that does not have a customer_id.

8. You will also want to call this method in the controller, like the previous plan creation method:

token = params[:stripeToken] # Token variable in the controller passed to model with customer payment information.
Enrollment.create_stripe_customer(current_user, current_course, token) if current_user.customer_id.nil?

9. Creating A Subscription:

def self.create_stripe_subscription(user, course, enroll)
  customer = Stripe::Customer.retrieve(user.customer_id.to_s, :stripe_account => course.user.uid)
  subscription = customer.subscriptions.create({
    :plan => enroll.plan_id,
    :application_fee_percent => 25},
    {:stripe_account => course.user.uid}
  enroll.update(subscription_id: subscription.id)

10. Finally, you'll want to retrieve(from the connected Stripe account) the customer from stripe using the customer_id that was saved on the current_user table. Set this retrieval to a variable and use this variable to create a subscription. Inside the subscription you will need to call the plan_id we saved, add an application fee(if you want), and create this on the connected users Stripe account(:stripe_account). Make sure to save this subscription ID(I saved mine to the same enrollment object where plan_id, course_id, and user_id are.)

11. Make sure to retrieve the customer so you can find the plan and subscription that were used.

I hope that this posting clears up any confusion you have when setting up Stripe in this manner.