app/concerns/koudoku/subscription.rb
def processing!

      # if their package level has changed ..
      if changing_plans?

        prepare_for_plan_change

        # and a customer exists in stripe ..
        if stripe_id.present?

          # fetch the customer.
          customer = Stripe::Customer.retrieve(self.stripe_id)

          # if a new plan has been selected
          if self.plan.present?

            # Record the new plan pricing.
            self.current_price = self.plan.price

            prepare_for_downgrade if downgrading?
            prepare_for_upgrade if upgrading?

            # update the package level with stripe.
            customer.update_subscription(
              plan: self.plan.stripe_id,
              prorate: Koudoku.prorate,
              cancel_at_period_end: false
            )

            self.cancel_at = nil

            finalize_downgrade! if downgrading?
            finalize_upgrade! if upgrading?

          # if no plan has been selected.
          else

            if Koudoku.cancel_at_period_end

              # since the old koudoku method for canceling a subscription was unsetting the plan, we need to
              # look up the old plan manually.
              plan_was = Plan.find(self.plan_id_was)

              result = customer.update_subscription(
                # we're not actually changing the plan, but stripe requires this param for some reason.
                plan: plan_was.stripe_id,
                cancel_at_period_end: true
              )

              # we're adhering to the original koudoku interface of canceling a subscription by unsetting the plan.
              # however, we actually don't want to unset the plan yet, because the customer technically still has a
              # plan until the end of the billing period.
              self.plan = plan_was

              # keep track of when stripe says the plan should actually be removed from the subscription.
              self.cancel_at = Time.at(result['current_period_end'])

            else

              prepare_for_cancelation

              # Remove the current pricing.
              self.current_price = nil

              # delete the subscription.
              customer.cancel_subscription

              finalize_cancelation!

            end

          end

        # when customer DOES NOT exist in stripe ..
        else
          # if a new plan has been selected
          if self.plan.present?

            # Record the new plan pricing.
            self.current_price = self.plan.price

            prepare_for_new_subscription
            prepare_for_upgrade

            begin
              raise Koudoku::NilCardToken, "No card token received. Check for JavaScript errors breaking Stripe.js on the previous page." unless credit_card_token.present?

              customer_attributes = {
                description: subscription_owner_description,
                email: subscription_owner_email,
                card: credit_card_token, # obtained with Stripe.js
                metadata: subscription_owner_metadata
              }

              # If the class we're being included in supports Rewardful ..
              if respond_to? :rewardful_id
                if rewardful_id.present?
                  customer_attributes[:metadata] = {referral: rewardful_id}
                end
              end

              # If the class we're being included in supports coupons ..
              if respond_to? :coupon
                if coupon.present? and coupon.free_trial?
                  customer_attributes[:trial_end] = coupon.free_trial_ends.to_i
                end
              end

              customer_attributes[:coupon] = @coupon_code if @coupon_code

              # create a customer at that package level.
              customer = Stripe::Customer.create(customer_attributes)

              finalize_new_customer!(customer.id, plan.price)

              subscription_attributes = {
                customer: customer.id,
                items:[
                  {
                    plan: self.plan.stripe_id,
                    quantity: subscription_owner_quantity
                  }
                ],
                trial_from_plan: true
              }

              # If the class we're being included in supports Link Mink ..
              if respond_to? :link_mink_id
                if link_mink_id.present?
                  subscription_attributes[:metadata] = {lm_data: link_mink_id}
                end
              end

              Stripe::Subscription.create(subscription_attributes)

            rescue Stripe::CardError => card_error
              errors[:base] << card_error.message
              card_was_declined
              throw :abort
            end

            # store the customer id.
            self.stripe_id = customer.id
            self.last_four = customer.sources.retrieve(customer.default_source).last4

            finalize_new_subscription!
            finalize_upgrade!

          else

            # This should never happen.

            self.plan_id = nil

            # Remove any plan pricing.
            self.current_price = nil

          end

        end

        finalize_plan_change!

      # if they're updating their credit card details.
      elsif self.credit_card_token.present?

        prepare_for_card_update

        # fetch the customer.
        customer = Stripe::Customer.retrieve(self.stripe_id)
        customer.source = self.credit_card_token
        customer.save

        # update the last four based on this new card.
        self.last_four = customer.sources.retrieve(customer.default_source).last4
        finalize_card_update!

      end
    end
# We don't store these one-time use tokens, but this is what Stripe provides
# client-side after storing the credit card information.
We don't store these one-time use tokens, but this is what Stripe provides
client-side after storing the credit card information.
We don ' t store these one - time use tokens but this is what Stripe provides client - side after storing the credit card information .
def processing!
      if changing_plans?
        prepare_for_plan_change
        if stripe_id.present?
          customer = Stripe::Customer.retrieve(self.stripe_id)
          if self.plan.present?
            self.current_price = self.plan.price
            prepare_for_downgrade if downgrading?
            prepare_for_upgrade if upgrading?
            customer.update_subscription(
              plan: self.plan.stripe_id,
              prorate: Koudoku.prorate,
              cancel_at_period_end: false
            )
            self.cancel_at = nil
            finalize_downgrade! if downgrading?
            finalize_upgrade! if upgrading?
          else
            if Koudoku.cancel_at_period_end
              plan_was = Plan.find(self.plan_id_was)
              result = customer.update_subscription(
                plan: plan_was.stripe_id,
                cancel_at_period_end: true
              )
              self.plan = plan_was
              self.cancel_at = Time.at(result['current_period_end'])
            else
              prepare_for_cancelation
              self.current_price = nil
              customer.cancel_subscription
              finalize_cancelation!
            end
          end
        else
          if self.plan.present?
            self.current_price = self.plan.price
            prepare_for_new_subscription
            prepare_for_upgrade
            begin
              raise Koudoku::NilCardToken, "No card token received. Check for JavaScript errors breaking Stripe.js on the previous page." unless credit_card_token.present?
              customer_attributes = {
                description: subscription_owner_description,
                email: subscription_owner_email,
                card: credit_card_token, 
                metadata: subscription_owner_metadata
              }
              if respond_to? :rewardful_id
                if rewardful_id.present?
                  customer_attributes[:metadata] = {referral: rewardful_id}
                end
              end
              if respond_to? :coupon
                if coupon.present? and coupon.free_trial?
                  customer_attributes[:trial_end] = coupon.free_trial_ends.to_i
                end
              end
              customer_attributes[:coupon] = @coupon_code if @coupon_code
              customer = Stripe::Customer.create(customer_attributes)
              finalize_new_customer!(customer.id, plan.price)
              subscription_attributes = {
                customer: customer.id,
                items:[
                  {
                    plan: self.plan.stripe_id,
                    quantity: subscription_owner_quantity
                  }
                ],
                trial_from_plan: true
              }
              if respond_to? :link_mink_id
                if link_mink_id.present?
                  subscription_attributes[:metadata] = {lm_data: link_mink_id}
                end
              end
              Stripe::Subscription.create(subscription_attributes)
            rescue Stripe::CardError => card_error
              errors[:base] << card_error.message
              card_was_declined
              throw :abort
            end
            self.stripe_id = customer.id
            self.last_four = customer.sources.retrieve(customer.default_source).last4
            finalize_new_subscription!
            finalize_upgrade!
          else
            self.plan_id = nil
            self.current_price = nil
          end
        end
        finalize_plan_change!
      elsif self.credit_card_token.present?
        prepare_for_card_update
        customer = Stripe::Customer.retrieve(self.stripe_id)
        customer.source = self.credit_card_token
        customer.save
        self.last_four = customer.sources.retrieve(customer.default_source).last4
        finalize_card_update!
      end
    end
def processing! if changing_plans? prepare_for_plan_change if stripe_id . present? customer = Stripe :: Customer . retrieve ( self . stripe_id ) if self . plan . present? self . current_price = self . plan . price prepare_for_downgrade if downgrading? prepare_for_upgrade if upgrading? customer . update_subscription ( plan : self . plan . stripe_id , prorate : Koudoku . prorate , cancel_at_period_end : false ) self . cancel_at = nil finalize_downgrade! if downgrading? finalize_upgrade! if upgrading? else if Koudoku . cancel_at_period_end plan_was = Plan . find ( self . plan_id_was ) result = customer . update_subscription ( plan : plan_was . stripe_id , cancel_at_period_end : true ) self . plan = plan_was self . cancel_at = Time . at ( result [ 'current_period_end' ] ) else prepare_for_cancelation self . current_price = nil customer . cancel_subscription finalize_cancelation! end end else if self . plan . present? self . current_price = self . plan . price prepare_for_new_subscription prepare_for_upgrade begin raise Koudoku :: NilCardToken , "No card token received. Check for JavaScript errors breaking Stripe.js on the previous page." unless credit_card_token . present? customer_attributes = { description : subscription_owner_description , email : subscription_owner_email , card : credit_card_token , metadata : subscription_owner_metadata } if respond_to? :rewardful_id if rewardful_id . present? customer_attributes [ :metadata ] = { referral : rewardful_id } end end if respond_to? :coupon if coupon . present? and coupon . free_trial? customer_attributes [ :trial_end ] = coupon . free_trial_ends . to_i end end customer_attributes [ :coupon ] = @coupon_code if @coupon_code customer = Stripe :: Customer . create ( customer_attributes ) finalize_new_customer! ( customer . id , plan . price ) subscription_attributes = { customer : customer . id , items : [ { plan : self . plan . stripe_id , quantity : subscription_owner_quantity } ] , trial_from_plan : true } if respond_to? :link_mink_id if link_mink_id . present? subscription_attributes [ :metadata ] = { lm_data : link_mink_id } end end Stripe :: Subscription . create ( subscription_attributes ) rescue Stripe :: CardError => card_error errors [ :base ] << card_error . message card_was_declined throw :abort end self . stripe_id = customer . id self . last_four = customer . sources . retrieve ( customer . default_source ) . last4 finalize_new_subscription! finalize_upgrade! else self . plan_id = nil self . current_price = nil end end finalize_plan_change! elsif self . credit_card_token . present? prepare_for_card_update customer = Stripe :: Customer . retrieve ( self . stripe_id ) customer . source = self . credit_card_token customer . save self . last_four = customer . sources . retrieve ( customer . default_source ) . last4 finalize_card_update! end end
We don't store these one-time use tokens, but this is what Stripe provides
client-side after storing the credit card information.
We don ' t store these one - time use tokens but this is what Stripe provides client - side after storing the credit card information .
# if their package level has changed .. # and a customer exists in stripe .. # fetch the customer. # if a new plan has been selected # Record the new plan pricing. # update the package level with stripe. # if no plan has been selected. # since the old koudoku method for canceling a subscription was unsetting the plan, we need to # look up the old plan manually. # we're not actually changing the plan, but stripe requires this param for some reason. # we're adhering to the original koudoku interface of canceling a subscription by unsetting the plan. # however, we actually don't want to unset the plan yet, because the customer technically still has a # plan until the end of the billing period. # keep track of when stripe says the plan should actually be removed from the subscription. # Remove the current pricing. # delete the subscription. # when customer DOES NOT exist in stripe .. # if a new plan has been selected # Record the new plan pricing. # obtained with Stripe.js # If the class we're being included in supports Rewardful .. # If the class we're being included in supports coupons .. # create a customer at that package level. # If the class we're being included in supports Link Mink .. # store the customer id. # This should never happen. # Remove any plan pricing. # if they're updating their credit card details. # fetch the customer. # update the last four based on this new card.