Class: UsageCredits::CreditSubscriptionPlan
- Inherits:
-
Object
- Object
- UsageCredits::CreditSubscriptionPlan
- Defined in:
- lib/usage_credits/models/credit_subscription_plan.rb
Overview
A DSL to define subscription plans that give credits to users on a recurring basis.
The actual credit fulfillment is handled by the PaySubscriptionExtension, which monitors subscription events (creation, renewal, etc) and adds credits to the user’s wallet accordingly.
Defined Under Namespace
Classes: CreditGiver
Constant Summary collapse
- MIN_PERIOD =
1.day
Instance Attribute Summary collapse
-
#credit_expiration_period ⇒ Object
readonly
Returns the value of attribute credit_expiration_period.
-
#credits_per_period ⇒ Object
readonly
Returns the value of attribute credits_per_period.
-
#expire_credits_on_cancel ⇒ Object
readonly
Returns the value of attribute expire_credits_on_cancel.
-
#fulfillment_period ⇒ Object
Returns the value of attribute fulfillment_period.
-
#metadata ⇒ Object
readonly
Returns the value of attribute metadata.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#processor_plan_ids ⇒ Object
readonly
Returns the value of attribute processor_plan_ids.
-
#rollover_enabled ⇒ Object
readonly
Returns the value of attribute rollover_enabled.
-
#signup_bonus_credits ⇒ Object
readonly
Returns the value of attribute signup_bonus_credits.
-
#trial_credits ⇒ Object
readonly
Returns the value of attribute trial_credits.
Instance Method Summary collapse
- #base_metadata ⇒ Object
-
#create_checkout_session(user, success_url:, cancel_url:, processor: :stripe) ⇒ Object
Create a checkout session for this subscription plan.
- #create_stripe_checkout_session(user, plan_id, success_url, cancel_url) ⇒ Object
-
#expire_after(duration) ⇒ void
Configure credit expiration after subscription cancellation.
-
#fulfillment_period_display ⇒ Object
Helper Methods =========================================.
-
#gives(amount) ⇒ Object
Set base credits given each period.
-
#initialize(name) ⇒ CreditSubscriptionPlan
constructor
A new instance of CreditSubscriptionPlan.
-
#meta(hash) ⇒ Object
Add custom metadata.
- #parsed_fulfillment_period ⇒ Object
-
#plan_id_for(processor) ⇒ Object
Get the plan ID for a specific processor.
-
#processor_plan(processor, id) ⇒ Object
Set the processor-specific plan ID.
-
#signup_bonus(amount) ⇒ Object
One-time signup bonus credits.
-
#stripe_price(id = nil) ⇒ Object
Shorthand for Stripe price ID.
-
#trial_includes(amount) ⇒ Object
Credits given during trial period.
-
#unused_credits(behavior) ⇒ Object
Configure whether unused credits roll over between periods.
-
#validate! ⇒ Object
Validation =========================================.
Constructor Details
#initialize(name) ⇒ CreditSubscriptionPlan
Returns a new instance of CreditSubscriptionPlan.
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 24 def initialize(name) @name = name @processor_plan_ids = {} # Store processor-specific plan IDs @fulfillment_period = nil @credits_per_period = 0 @signup_bonus_credits = 0 @trial_credits = 0 @rollover_enabled = false @expire_credits_on_cancel = false @credit_expiration_period = nil @metadata = {} end |
Instance Attribute Details
#credit_expiration_period ⇒ Object (readonly)
Returns the value of attribute credit_expiration_period.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def credit_expiration_period @credit_expiration_period end |
#credits_per_period ⇒ Object (readonly)
Returns the value of attribute credits_per_period.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def credits_per_period @credits_per_period end |
#expire_credits_on_cancel ⇒ Object (readonly)
Returns the value of attribute expire_credits_on_cancel.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def expire_credits_on_cancel @expire_credits_on_cancel end |
#fulfillment_period ⇒ Object
Returns the value of attribute fulfillment_period.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def fulfillment_period @fulfillment_period end |
#metadata ⇒ Object (readonly)
Returns the value of attribute metadata.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def @metadata end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def name @name end |
#processor_plan_ids ⇒ Object (readonly)
Returns the value of attribute processor_plan_ids.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def processor_plan_ids @processor_plan_ids end |
#rollover_enabled ⇒ Object (readonly)
Returns the value of attribute rollover_enabled.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def rollover_enabled @rollover_enabled end |
#signup_bonus_credits ⇒ Object (readonly)
Returns the value of attribute signup_bonus_credits.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def signup_bonus_credits @signup_bonus_credits end |
#trial_credits ⇒ Object (readonly)
Returns the value of attribute trial_credits.
12 13 14 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 12 def trial_credits @trial_credits end |
Instance Method Details
#base_metadata ⇒ Object
165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 165 def { purchase_type: "credit_subscription", subscription_name: name, fulfillment_period: fulfillment_period_display, credits_per_period: credits_per_period, signup_bonus_credits: signup_bonus_credits, trial_credits: trial_credits, rollover_enabled: rollover_enabled, expire_credits_on_cancel: expire_credits_on_cancel, credit_expiration_period: credit_expiration_period&.to_i, metadata: } end |
#create_checkout_session(user, success_url:, cancel_url:, processor: :stripe) ⇒ Object
Create a checkout session for this subscription plan
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 111 def create_checkout_session(user, success_url:, cancel_url:, processor: :stripe) raise ArgumentError, "User must respond to payment_processor" unless user.respond_to?(:payment_processor) raise ArgumentError, "No fulfillment period configured for plan: #{name}" unless fulfillment_period plan_id = plan_id_for(processor) raise ArgumentError, "No #{processor.to_s.titleize} plan ID configured for plan: #{name}" unless plan_id case processor when :stripe create_stripe_checkout_session(user, plan_id, success_url, cancel_url) else raise ArgumentError, "Unsupported payment processor: #{processor}" end end |
#create_stripe_checkout_session(user, plan_id, success_url, cancel_url) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 151 def create_stripe_checkout_session(user, plan_id, success_url, cancel_url) user.payment_processor.checkout( mode: "subscription", line_items: [{ price: plan_id, quantity: 1 }], success_url: success_url, cancel_url: cancel_url, payment_intent_data: { metadata: }, subscription_data: { metadata: } ) end |
#expire_after(duration) ⇒ void
This method returns an undefined value.
Configure credit expiration after subscription cancellation
When a subscription is cancelled, you can control what happens to remaining credits:
-
By default (if this is not called), users keep their credits forever
-
If called with a duration, credits expire after that grace period
-
If called with nil/0, credits expire immediately on cancellation
77 78 79 80 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 77 def expire_after(duration) @expire_credits_on_cancel = true @credit_expiration_period = duration end |
#fulfillment_period_display ⇒ Object
Helper Methods
143 144 145 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 143 def fulfillment_period_display fulfillment_period.is_a?(ActiveSupport::Duration) ? fulfillment_period.inspect : fulfillment_period end |
#gives(amount) ⇒ Object
Set base credits given each period
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 42 def gives(amount) if amount.is_a?(UsageCredits::Cost::Fixed) @credits_per_period = amount.amount @fulfillment_period = UsageCredits::PeriodParser.normalize_period(amount.period || 1.month) self else @credits_per_period = amount.to_i CreditGiver.new(self) end end |
#meta(hash) ⇒ Object
Add custom metadata
83 84 85 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 83 def (hash) @metadata.merge!(hash) end |
#parsed_fulfillment_period ⇒ Object
147 148 149 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 147 def parsed_fulfillment_period UsageCredits::PeriodParser.parse_period(@fulfillment_period) end |
#plan_id_for(processor) ⇒ Object
Get the plan ID for a specific processor
97 98 99 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 97 def plan_id_for(processor) processor_plan_ids[processor.to_sym] end |
#processor_plan(processor, id) ⇒ Object
Set the processor-specific plan ID
92 93 94 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 92 def processor_plan(processor, id) processor_plan_ids[processor.to_sym] = id end |
#signup_bonus(amount) ⇒ Object
One-time signup bonus credits
54 55 56 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 54 def signup_bonus(amount) @signup_bonus_credits = amount.to_i end |
#stripe_price(id = nil) ⇒ Object
Shorthand for Stripe price ID
102 103 104 105 106 107 108 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 102 def stripe_price(id = nil) if id.nil? plan_id_for(:stripe) # getter else processor_plan(:stripe, id) # setter end end |
#trial_includes(amount) ⇒ Object
Credits given during trial period
59 60 61 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 59 def trial_includes(amount) @trial_credits = amount.to_i end |
#unused_credits(behavior) ⇒ Object
Configure whether unused credits roll over between periods
64 65 66 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 64 def unused_credits(behavior) @rollover_enabled = (behavior == :rollover) end |
#validate! ⇒ Object
Validation
130 131 132 133 134 135 136 137 |
# File 'lib/usage_credits/models/credit_subscription_plan.rb', line 130 def validate! raise ArgumentError, "Name can't be blank" if name.blank? raise ArgumentError, "Credits per period must be greater than 0" unless credits_per_period.to_i.positive? raise ArgumentError, "Fulfillment period must be set" if fulfillment_period.nil? raise ArgumentError, "Signup bonus credits must be greater than or equal to 0" if signup_bonus_credits.to_i.negative? raise ArgumentError, "Trial credits must be greater than or equal to 0" if trial_credits.to_i.negative? true end |