فهرست منبع

Merge pull request #25166 from overleaf/kh-cancel-subscription

[web] support canceling Stripe subscription

GitOrigin-RevId: a72ccb20fbef9b6662cdfa1dcffacbd76dcb694c
M Fahru 1 سال پیش
والد
کامیت
dd3ae65bd2

+ 5 - 1
services/web/app/src/Features/Subscription/LimitationsManager.js

@@ -128,7 +128,11 @@ async function userHasSubscription(user) {
   )
   let hasValidSubscription = false
   if (subscription) {
-    if (subscription.recurlySubscription_id || subscription.customAccount) {
+    if (
+      subscription.recurlySubscription_id ||
+      subscription.paymentProvider?.subscriptionId ||
+      subscription.customAccount
+    ) {
       hasValidSubscription = true
     }
   }

+ 5 - 18
services/web/app/src/Features/Subscription/SubscriptionHandler.js

@@ -12,6 +12,7 @@ const EmailHandler = require('../Email/EmailHandler')
 const { callbackify } = require('@overleaf/promise-utils')
 const UserUpdater = require('../User/UserUpdater')
 const { NotFoundError } = require('../Errors/Errors')
+const Modules = require('../../infrastructure/Modules')
 
 /**
  * @import { PaymentProviderSubscription, PaymentProviderSubscriptionChange } from './PaymentProviderEntities'
@@ -149,10 +150,7 @@ async function cancelSubscription(user) {
     const { hasSubscription, subscription } =
       await LimitationsManager.promises.userHasSubscription(user)
     if (hasSubscription && subscription != null) {
-      await RecurlyClient.promises.cancelSubscriptionByUuid(
-        subscription.recurlySubscription_id
-      )
-      await _updateSubscriptionFromRecurly(subscription)
+      await Modules.promises.hooks.fire('cancelPaidSubscription', subscription)
       const emailOpts = {
         to: user.email,
         first_name: user.first_name,
@@ -180,10 +178,10 @@ async function reactivateSubscription(user) {
     const { hasSubscription, subscription } =
       await LimitationsManager.promises.userHasSubscription(user)
     if (hasSubscription && subscription != null) {
-      await RecurlyClient.promises.reactivateSubscriptionByUuid(
-        subscription.recurlySubscription_id
+      await Modules.promises.hooks.fire(
+        'reactivatePaidSubscription',
+        subscription
       )
-      await _updateSubscriptionFromRecurly(subscription)
       EmailHandler.sendEmail(
         'reactivatedSubscription',
         { to: user.email },
@@ -267,17 +265,6 @@ async function extendTrial(subscription, daysToExend) {
   )
 }
 
-async function _updateSubscriptionFromRecurly(subscription) {
-  const recurlySubscription = await RecurlyWrapper.promises.getSubscription(
-    subscription.recurlySubscription_id,
-    {}
-  )
-  await SubscriptionUpdater.promises.updateSubscriptionFromRecurly(
-    recurlySubscription,
-    subscription
-  )
-}
-
 /**
  * Preview the effect of purchasing an add-on
  *

+ 13 - 0
services/web/test/unit/src/Subscription/LimitationsManagerTests.js

@@ -434,6 +434,19 @@ describe('LimitationsManager', function () {
       expect(hasSubscription).to.be.true
     })
 
+    it('should return true if the paymentProvider field is set', async function () {
+      this.SubscriptionLocator.promises.getUsersSubscription = sinon
+        .stub()
+        .resolves({
+          paymentProvider: {
+            subscriptionId: '1234',
+          },
+        })
+      const { hasSubscription } =
+        await this.LimitationsManager.promises.userHasSubscription(this.user)
+      expect(hasSubscription).to.be.true
+    })
+
     it('should return false if the recurly token is not set', async function () {
       this.SubscriptionLocator.promises.getUsersSubscription.resolves({})
       const { hasSubscription } =

+ 13 - 10
services/web/test/unit/src/Subscription/SubscriptionHandlerTests.js

@@ -156,6 +156,13 @@ describe('SubscriptionHandler', function () {
         '../Email/EmailHandler': this.EmailHandler,
         '../Analytics/AnalyticsManager': this.AnalyticsManager,
         '../User/UserUpdater': this.UserUpdater,
+        '../../infrastructure/Modules': (this.Modules = {
+          promises: {
+            hooks: {
+              fire: sinon.stub(),
+            },
+          },
+        }),
       },
     })
   })
@@ -426,12 +433,10 @@ describe('SubscriptionHandler', function () {
       })
 
       it('should cancel the subscription', function () {
-        this.RecurlyClient.promises.cancelSubscriptionByUuid.called.should.equal(
-          true
+        expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
+          'cancelPaidSubscription',
+          this.subscription
         )
-        this.RecurlyClient.promises.cancelSubscriptionByUuid
-          .calledWith(this.subscription.recurlySubscription_id)
-          .should.equal(true)
       })
 
       it('should send the email after 1 hour', function () {
@@ -626,12 +631,10 @@ describe('SubscriptionHandler', function () {
       })
 
       it('should reactivate the subscription', function () {
-        this.RecurlyClient.promises.reactivateSubscriptionByUuid.called.should.equal(
-          true
+        expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
+          'reactivatePaidSubscription',
+          this.subscription
         )
-        this.RecurlyClient.promises.reactivateSubscriptionByUuid
-          .calledWith(this.subscription.recurlySubscription_id)
-          .should.equal(true)
       })
 
       it('should send a notification email', function () {