From a302ff1597aed806a76318d16577db0e033ad9e6 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Thu, 25 Mar 2021 12:42:59 +0000 Subject: [PATCH] Added support for smart_cancel options https://github.com/TryGhost/Team/issues/530 This option will check to see if a subscription is in an unpaid or past due state, and if so, will cancel the subscription immediately, rather than cancelling at the period end. --- .../lib/controllers/member/index.js | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/ghost/members-api/lib/controllers/member/index.js b/ghost/members-api/lib/controllers/member/index.js index 0756613920..8944e1ba77 100644 --- a/ghost/members-api/lib/controllers/member/index.js +++ b/ghost/members-api/lib/controllers/member/index.js @@ -24,20 +24,21 @@ module.exports = class MemberController { const identity = req.body.identity; const subscriptionId = req.params.id; const cancelAtPeriodEnd = req.body.cancel_at_period_end; + const smartCancel = req.body.smart_cancel; const cancellationReason = req.body.cancellation_reason; const planName = req.body.planName; - if (cancelAtPeriodEnd === undefined && planName === undefined) { + if (cancelAtPeriodEnd === undefined && planName === undefined && smartCancel === undefined) { throw new errors.BadRequestError({ message: 'Updating subscription failed!', - help: 'Request should contain "cancel_at_period_end" or "planName" field.' + help: 'Request should contain "cancel_at_period_end" or "planName" or "smart_cancel" field.' }); } - if ((cancelAtPeriodEnd === undefined || cancelAtPeriodEnd === false) && cancellationReason !== undefined) { + if ((cancelAtPeriodEnd === undefined || cancelAtPeriodEnd === false) && !smartCancel && cancellationReason !== undefined) { throw new errors.BadRequestError({ message: 'Updating subscription failed!', - help: '"cancellation_reason" field requires the "cancel_at_period_end" field to be true.' + help: '"cancellation_reason" field requires the "cancel_at_period_end" or "smart_cancel" field to be true.' }); } @@ -92,6 +93,32 @@ module.exports = class MemberController { cancellationReason } }); + } else if (smartCancel) { + const currentSubscription = await this._memberRepository.getSubscription({ + email, + subscription: { + subscription_id: subscriptionId + } + }); + + if (['past_due', 'unpaid'].includes(currentSubscription.status)) { + await this._memberRepository.cancelSubscription({ + email, + subscription: { + subscription_id: subscriptionId, + cancellationReason + } + }); + } else { + await this._memberRepository.updateSubscription({ + email, + subscription: { + subscription_id: subscriptionId, + cancel_at_period_end: true, + cancellationReason + } + }); + } } res.writeHead(204);