Rails Stripe Retrieve ID Error "No such plan"

Viewed 1572

So my Plan says Stripe::InvalidRequestError at /orders/26/payments
No such plan: The title of my plan.
This code should check if the the plan already exists and if not create it and subscribe the user to it. I thought this worked because it was working for the case where I already had a plan with the same ID and it said "Plan already exists". How can I prevent this Error from happening?
This is my code:

class PaymentsController < ApplicationController
  before_action :set_order

  def new
  end

  def create
   @user = current_user

   customer = Stripe::Customer.create(
   source: params[:stripeToken],
   email:  params[:stripeEmail],
   )

# Storing the customer.id in the customer_id field of user
  @user.customer_id = customer.id

   @plan = Stripe::Plan.retrieve(@order.service.title)
    unless @plan
     plan = Stripe::Plan.create(
      :name => @order.service.title,
      :id => @order.service.title,
      :interval => "month",
      :currency => @order.amount.currency,
      :amount => @order.amount_pennies,
      )
    else
     subscription = Stripe::Subscription.create(
       :customer => @user.customer_id,
       :plan => @order.service.title
      )
    end

  @order.update(payment: plan.to_json, state: 'paid')
  redirect_to order_path(@order)

  rescue Stripe::CardError => e
  flash[:error] = e.message
  redirect_to new_order_payment_path(@order)

  end

  private

  def set_order
    @order = Order.where(state: 'pending').find(params[:order_id])
  end

end
2 Answers

Little bit improved version. It's sad that there is no way to check if plan exists and you have to rely on exception swallowing it. Here is my version, it tries to retrieve the plan, if error is 404, it creates the plan. Otherwise, lets exception to pop up. So it won't swallow all of the exceptions, which is important IMO when you work with finance API.

def retrieve_or_create_plan(id)
  begin
    Stripe::Plan.retrieve(id)
  rescue Stripe::InvalidRequestError => e
    if e.response.http_status == 404
      Stripe::Plan.create(
        name: 'Your plan name',
        id: id,
        interval: :month,
        currency: :usd,
        amount: 100
      )
    else
      raise e
    end
  end
end
Related