Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show user subscription as cancelled after billing period

I am using Stripe for my subscriptions and I have it set so when a user cancels their subscription (to turn off automatic renewal) it will keep the subscription active until the end of the billing period on Stripe.

The action works via Stripe, but how can I setup so that the cancelled column in my database takes the same affect? Currently if the user clicks on the cancel subscription link it will mark their cancelled column to 1. I would like for it to not mark as cancelled until the end of their billing period so the user can continue have access to the website until their final billing day (I have autorenwal turned on)

I have read txdavidtx suggestion. What he suggests would mark all Users as cancelled at the end of their billing period. That method would not fit with what I am looking to accomplish.

I have subscriptions set to autorenew. I would need a cancel action created that would only mark the current_user as cancelled at the end of their billing period.

For example:

User A signs up for the monthly subscription on September 27. User A decides on December 15 they want to cancel their subscription. User A still has 12 days left in their subscription. User A clicks on the cancel link. User A has autorenew and subscription cancelled in their PayPal or Stripe account. Inside my database their cancelled attribute value will not change until those 12 days have finished (December 27).

If someone can assist that would be great.

Subscriptions controller:

  def new
    plan = Plan.find(params[:plan_id])
    @subscription = plan.subscriptions.build
    render layout: 'new_application'
    if params[:PayerID]
      @subscription.paypal_customer_token = params[:PayerID]
      @subscription.paypal_payment_token = params[:token]
      @subscription.email = @subscription.paypal.checkout_details.email
    end
  end

  def create
    @subscription = Subscription.new(params[:subscription])
    if @subscription.save_with_payment
      redirect_to @subscription, :notice => "Thank you for subscribing!"
    else
      render :new
    end
  end

  def show
    @subscription = Subscription.find(params[:id])
    render layout: 'new_application'
  end

  def paypal_checkout
    plan = Plan.find(params[:plan_id])
    subscription = plan.subscriptions.build
    redirect_to subscription.paypal.checkout_url(
      return_url: new_subscription_url(:plan_id => plan.id),
      cancel_url: root_url
    )
  end

    def updatesubscription
      @user = current_user
      @customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
      if @user.subscription.plan_id == 12
      @customer.update_subscription(:plan => "1", :prorate => true)
      current_user.subscription.update_attributes(:plan_id => 1)
      flash.alert = 'Your subscription has been changed to monthly!'
      redirect_to root_url
    elsif @user.subscription.plan_id == 1
      @customer.update_subscription(:plan => "12", :prorate => true)
      current_user.subscription.update_attributes(:plan_id => 12)
     current_user.save!
      flash.alert = 'Your subscription has been changed to annually!'
      redirect_to root_url
    end
     end

     def cancelsubscription
       @user = current_user
         @customer = Stripe::Customer.retrieve(@user.subscription.stripe_customer_token)
         @customer.cancel_subscription(:at_period_end => true) 
         current_user.subscription.update_attributes(:cancelled => 1)
         current_user.save!
         flash.alert = 'Your subscription has been cancelled successfully!'
         redirect_to root_url
       end

       def showcard
         @user = current_user
         Stripe::Customer.retrieve(@user.subscription.stripe_customer_token).cards.all()
       end

           def suspend
             @user = current_user
             @user.subscription.suspend_paypal
             current_user.subscription.update_attributes(:cancelled => 1)
               flash.alert = 'Billing has been suspended!'
                redirect_to root_url
           end

           def reactivate
             @user = current_user
             @user.subscription.reactivate_paypal
             current_user.subscription.update_attributes(:cancelled => nil)
               flash.alert = 'Billing has been activated!'
                redirect_to root_url
           end


               def edit_card
                 @user = current_user
               end

               def update_card
                 @user = current_user
                 card_info = {
                   name:    params[:name],
                   number:    params[:number],
                   exp_month: params[:date][:month],
                   exp_year:  params[:date][:year],
                   cvc:       params[:cvc]
                 }
                 if @user.subscription.update_card(@subscriber, card_info)
                   flash.alert = 'Saved. Your card information has been updated.'
                   redirect_to root_url
                 else
                   flash.alert = 'Stripe reported an error while updating your card. Please try again.'
                   redirect_to root_url
                 end
               end
end
like image 907
Cornelius Wilson Avatar asked Feb 02 '26 05:02

Cornelius Wilson


1 Answers

I think the easiest way is to use stripe webhooks, where as soon as the subscription ends stripe will ping your system with a customer.subscription.deleted event and at that point you should just cancel the user subscription.

The setup is really easy.

  1. You just go to your settings page and add a webhook url and then stripe will start sending you system events.
  2. Then Create a stripe events controller which will parse stripe events in the backend.
  3. Detect the user and cancel his subscription with at_period_end params true

    customer = Stripe::Customer.retrieve("cus_3R1W8PG2DmsmM9")
    customer.subscriptions.retrieve("sub_3R3PlB2YlJe84a").delete(:at_period_end => true
    

A customer.subscription.updated event is immediately triggered if you cancel a subscription at the end of the billing period instead, reflecting the change in the subscription’s cancel_at_period_end value. When the subscription is actually canceled at the end of the period, a customer.subscription.deleted event will occur. Stripe Doc

4- Then Setup your callback controller and detect subscription deleted

<pre>
class StripeEventsController

  skip_before_filter  :verify_authenticity_token

  def catch
    object = params[:data][:object]
    case params[:type]
    when "customer.subscription.deleted"
     customer = object[:id]
     user = User.find_by_stripe_id(customer)
     user.subscription.update_attributes(cancelled: "1")
    end
  end

end

like image 154
Kimooz Avatar answered Feb 04 '26 19:02

Kimooz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!