summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolò€ Rebughini <nicolo.rebughini@gmail.com>2020-11-16 14:43:58 +0100
committerNicolò€ Rebughini <nicolo.rebughini@gmail.com>2020-11-16 17:29:06 +0100
commit2043e4777eba02bc48692d6d45c78c8c99d3dd5c (patch)
treee477a3e11a3665167d7e9c951bf3631e6e12765b
parent6180dacde705b8cfb30229c0653df80202c58159 (diff)
Add config to ignore past unfulfilled installments
This implements a configuration to ignore past unfulfilled installments for subscriptions upon installments creations. Since failed installments (e.g. because of an expired credit card) are retried indefinitely, they can overlap and also be retried after another subscription cycle began. In this particular case, a customer who fixes their payment method after a new cycle, would be charged for double (or X times as much based on how long it passed) and sent double the quantity of the same product. Because in some cases this is not desirable, this adds a switch to skip any failed past installment when a new installment gets created under the same subscription.
-rw-r--r--README.md19
-rw-r--r--lib/generators/solidus_subscriptions/install/templates/initializer.rb7
-rw-r--r--lib/solidus_subscriptions/configuration.rb2
-rw-r--r--lib/solidus_subscriptions/processor.rb6
-rw-r--r--spec/lib/solidus_subscriptions/processor_spec.rb15
5 files changed, 46 insertions, 3 deletions
diff --git a/README.md b/README.md
index 5dbacb6..3d8a3b9 100644
--- a/README.md
+++ b/README.md
@@ -104,7 +104,7 @@ configuration:
```ruby
SolidusSubscriptions.configure do |config|
# ...
-
+
config.churn_buster_account_id = 'YOUR_CHURN_BUSTER_ACCOUNT_ID'
config.churn_buster_api_key = 'YOUR_CHURN_BUSTER_API_KEY'
end
@@ -113,6 +113,23 @@ end
The extension will take care of reporting successful/failed payments and payment method changes
to Churn Buster.
+### Failed installments retries
+
+The extension generates an installment for each subscription cycle, however some of them can fail
+(e.g. for an expired credit card). On each processor run the extension will try to complete all past
+failed installments, however this is not always the desired behaviour.
+
+If you want to process only the latest installment in each subscription, regardless of any number of
+failed installments prior to that, you can configure the extension like so:
+
+```ruby
+SolidusSubscriptions.configure do |config|
+ # ...
+
+ config.clear_past_installments = true
+end
+```
+
## Development
### Testing the extension
diff --git a/lib/generators/solidus_subscriptions/install/templates/initializer.rb b/lib/generators/solidus_subscriptions/install/templates/initializer.rb
index 150f439..a346412 100644
--- a/lib/generators/solidus_subscriptions/install/templates/initializer.rb
+++ b/lib/generators/solidus_subscriptions/install/templates/initializer.rb
@@ -82,4 +82,11 @@ SolidusSubscriptions.configure do |config|
# Your Churn Buster API key.
# config.churn_buster_api_key = 'YOUR_CHURN_BUSTER_API_KEY'
+
+ # =================================== Clear past installments ====================================
+ #
+ # This setting prevents the overlap of old failed installments (e.g. for an expired credit card)
+ # with new subscription cycles by clearing any past failed installment when a new one is created
+
+ # config.clear_past_installments = true
end
diff --git a/lib/solidus_subscriptions/configuration.rb b/lib/solidus_subscriptions/configuration.rb
index 9cf1408..13254be 100644
--- a/lib/solidus_subscriptions/configuration.rb
+++ b/lib/solidus_subscriptions/configuration.rb
@@ -4,7 +4,7 @@ module SolidusSubscriptions
class Configuration
attr_accessor(
:maximum_total_skips, :maximum_reprocessing_attempts, :churn_buster_account_id,
- :churn_buster_api_key,
+ :churn_buster_api_key, :clear_past_installments,
)
attr_writer(
diff --git a/lib/solidus_subscriptions/processor.rb b/lib/solidus_subscriptions/processor.rb
index 817d957..4946b5a 100644
--- a/lib/solidus_subscriptions/processor.rb
+++ b/lib/solidus_subscriptions/processor.rb
@@ -98,6 +98,12 @@ module SolidusSubscriptions
sub.advance_actionable_date
sub.cancel! if sub.pending_cancellation?
sub.deactivate! if sub.can_be_deactivated?
+ if SolidusSubscriptions.configuration.clear_past_installments
+ sub.installments.unfulfilled.each do |installment|
+ installment.actionable_date = nil
+ installment.save!
+ end
+ end
sub.installments.create!
end
end
diff --git a/spec/lib/solidus_subscriptions/processor_spec.rb b/spec/lib/solidus_subscriptions/processor_spec.rb
index b70d501..fcfdd2d 100644
--- a/spec/lib/solidus_subscriptions/processor_spec.rb
+++ b/spec/lib/solidus_subscriptions/processor_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe SolidusSubscriptions::Processor, :checkout do
expect(order_variant_ids).to match_array expected_ids
end
- it 'advances the subsription actionable dates' do
+ it 'advances the subscription actionable dates' do
subscription = actionable_subscriptions.first
current_date = subscription.actionable_date
@@ -108,6 +108,19 @@ RSpec.describe SolidusSubscriptions::Processor, :checkout do
end
end
+ context "when the config 'clear_past_installments' is enabled" do
+ it 'clears the past failed installments' do
+ allow(SolidusSubscriptions.configuration).to receive(:clear_past_installments).
+ and_return(true)
+
+ subject
+
+ failed_installments.each do |fi|
+ expect(fi.reload.actionable_date).to eq(nil)
+ end
+ end
+ end
+
context 'the subscriptions have different billing addresses' do
let!(:sub_to_different_address) do
create(:subscription, :actionable, :with_billing_address, user: user)