Class: CoreMerchant::SubscriptionManager

Inherits:
Object
  • Object
show all
Includes:
Concerns::SubscriptionManagerNotifications
Defined in:
lib/core_merchant/subscription_manager.rb

Overview

Manages subscriptions in CoreMerchant. This class is responsible for notifying listeners when subscription events occur and checking for and handling renewals. Attributes:

- `listeners` - An array of listeners that will be notified when subscription events occur.

Methods:

- `check_subscriptions` - Checks all subscriptions for renewals
- `add_listener(listener)` - Adds a listener to the list of listeners
- `no_payment_needed_for_renewal(subscription)` - Handles the case where no payment is needed for a renewal.
   Call when a subscription is renewed without payment.
- `processing_payment_for_renewal(subscription)` - Handles the case where payment is being processed for a renewal.
   Call when payment is being processed for a renewal.
- `payment_successful_for_renewal(subscription)` - Handles the case where payment was successful for a renewal.
   Call when payment was successful for a renewal.
- `payment_failed_for_renewal(subscription)` - Handles the case where payment failed for a renewal.
   Call when payment failed for a renewal.

Usage:

```ruby
manager = CoreMerchant.subscription_manager
manager.check_subscriptions

# ... somewhere else in the code ...
manager.payment_successful_for_renewal(subscription1)
manager.payment_failed_for_renewal(subscription2)
```

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSubscriptionManager

Returns a new instance of SubscriptionManager.



39
40
41
# File 'lib/core_merchant/subscription_manager.rb', line 39

def initialize
  @listeners = []
end

Instance Attribute Details

#listenersObject (readonly)

Returns the value of attribute listeners.



37
38
39
# File 'lib/core_merchant/subscription_manager.rb', line 37

def listeners
  @listeners
end

Instance Method Details

#add_listener(listener) ⇒ Object

Adds a listener to the list of listeners. You probably don’t need to call this method directly. Instead, set the listener in the configuration. config.subscription_listener_class = “MySubscriptionListener”



54
55
56
# File 'lib/core_merchant/subscription_manager.rb', line 54

def add_listener(listener)
  @listeners << listener
end

#cancel_subscription(subscription, reason:, at_period_end: true) ⇒ Object

Cancels the subscription. Parameters:

  • ‘reason`: Reason for cancellation

  • ‘at_period_end`: If true, the subscription will be canceled at the end of the current period. Otherwise, the subscription will be canceled immediately. Default is `true`.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/core_merchant/subscription_manager.rb', line 82

def cancel_subscription(subscription, reason:, at_period_end: true)
  subscription.transaction do
    if at_period_end
      subscription.transition_to_pending_cancellation!
    else
      subscription.transition_to_canceled!
    end
    subscription.update!(
      canceled_at: at_period_end ? subscription.current_period_end : Time.current,
      cancellation_reason: reason
    )
  end

  notify(subscription, :canceled, reason: reason, immediate: !at_period_end)
  subscription.cancellation_events.create!(reason: reason, at_period_end: at_period_end)
end

#check_cancellationsObject

Checks all subscriptions for cancellations. Called by ‘check_subscriptions`.



144
145
146
147
148
# File 'lib/core_merchant/subscription_manager.rb', line 144

def check_cancellations
  Subscription.find_each do |subscription|
    process_for_cancellation(subscription) if subscription.pending_cancellation?
  end
end

#check_renewalsObject

Checks all subscriptions for renewals. Called by ‘check_subscriptions`.



59
60
61
62
63
# File 'lib/core_merchant/subscription_manager.rb', line 59

def check_renewals
  Subscription.find_each do |subscription|
    process_for_renewal(subscription) if subscription.due_for_renewal?
  end
end

#check_subscriptionsObject

Checks all subscriptions for renewals and cancellations. Call this method periodically (probably daily) to check for subscriptions that need attention. This method will notify listeners when subscriptions are due for renewal or cancellation.



46
47
48
49
# File 'lib/core_merchant/subscription_manager.rb', line 46

def check_subscriptions
  check_renewals
  check_cancellations
end

#no_payment_needed_for_renewal(subscription) ⇒ Object

Call this method when a subscription is renewed without payment. It will renew the subscription and notify listeners.



112
113
114
# File 'lib/core_merchant/subscription_manager.rb', line 112

def no_payment_needed_for_renewal(subscription)
  renew_subscription(subscription)
end

#payment_failed_for_renewal(subscription) ⇒ Object

Call this method when payment failed for a renewal. It will transition the subscription to past due when in grace period, or expired if not.



132
133
134
135
136
137
138
139
140
141
# File 'lib/core_merchant/subscription_manager.rb', line 132

def payment_failed_for_renewal(subscription)
  is_in_grace_period = subscription.in_grace_period?
  if is_in_grace_period
    subscription.transition_to_past_due
    notify(subscription, :grace_period_started, days_remaining: subscription.days_remaining_in_grace_period)
  else
    subscription.transition_to_expired
    notify(subscription, :expired)
  end
end

#payment_successful_for_renewal(subscription) ⇒ Object

Call this method when payment was successful for a renewal. It will renew the subscription and notify listeners.



126
127
128
# File 'lib/core_merchant/subscription_manager.rb', line 126

def payment_successful_for_renewal(subscription)
  renew_subscription(subscription)
end

#process_for_cancellation(subscription) ⇒ Object

Processes a subscription for cancellation. This method is called when a subscription is pending cancellation.



152
153
154
155
156
# File 'lib/core_merchant/subscription_manager.rb', line 152

def process_for_cancellation(subscription)
  return unless subscription.transition_to_expired

  notify(subscription, :expired)
end

#process_for_renewal(subscription) ⇒ Object

Starts the subscription renewal process. This method is called when a subscription is due for renewal. It will in turn call notify the listener. When you receive a notification that a subscription is due for renewal, you should either call ‘no_payment_needed_for_renewal`, `processing_payment_for_renewal`, `payment_successful_for_renewal`, or `payment_failed_for_renewal` to continue the renewal process.



104
105
106
107
108
# File 'lib/core_merchant/subscription_manager.rb', line 104

def process_for_renewal(subscription)
  return unless subscription.transition_to_processing_renewal

  notify(subscription, :due_for_renewal)
end

#processing_payment_for_renewal(subscription) ⇒ Object

Call this method when payment is being processed for a renewal. This needs to be followed by either ‘payment_successful_for_renewal` or `payment_failed_for_renewal`.



118
119
120
121
122
# File 'lib/core_merchant/subscription_manager.rb', line 118

def processing_payment_for_renewal(subscription)
  return unless subscription.transition_to_processing_payment

  notify(subscription, :renewal_payment_processing)
end

#start_subscription(subscription) ⇒ Object

Starts the subscription. Sets the current period start and end dates based on the plan’s duration.



67
68
69
70
71
72
73
74
# File 'lib/core_merchant/subscription_manager.rb', line 67

def start_subscription(subscription)
  subscription.transaction do
    subscription.start_new_period
    subscription.transition_to_active!
  end

  notify(subscription, :started)
end