From 45d338730c6597c5793340cbdeaa3b3913fc2a11 Mon Sep 17 00:00:00 2001 From: Fabien O'Carroll Date: Mon, 10 May 2021 15:40:12 +0100 Subject: [PATCH] Updated webhook service to work with multiple products no-issue Since we do not necessarily have a single stripe product anymore, we should be checking if an invoice webhook is for a stripe product which we know about. We use the Products repository to search our database for one. --- .../members-api/lib/services/stripe-webhook/index.js | 12 ++++++++---- .../test/unit/lib/services/stripe-webhook.test.js | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/ghost/members-api/lib/services/stripe-webhook/index.js b/ghost/members-api/lib/services/stripe-webhook/index.js index 2688401ca3..6d08fa95f7 100644 --- a/ghost/members-api/lib/services/stripe-webhook/index.js +++ b/ghost/members-api/lib/services/stripe-webhook/index.js @@ -6,22 +6,22 @@ module.exports = class StripeWebhookService { * @param {object} deps * @param {any} deps.StripeWebhook * @param {import('../stripe-api')} deps.stripeAPIService - * @param {import('../stripe-plans')} deps.stripePlansService * @param {import('../../repositories/member')} deps.memberRepository + * @param {import('../../repositories/product')} deps.productRepository * @param {import('../../repositories/event')} deps.eventRepository * @param {any} deps.sendEmailWithMagicLink */ constructor({ StripeWebhook, stripeAPIService, - stripePlansService, + productRepository, memberRepository, eventRepository, sendEmailWithMagicLink }) { this._StripeWebhook = StripeWebhook; this._stripeAPIService = stripeAPIService; - this._stripePlansService = stripePlansService; + this._productRepository = productRepository; this._memberRepository = memberRepository; this._eventRepository = eventRepository; this._sendEmailWithMagicLink = sendEmailWithMagicLink; @@ -169,9 +169,13 @@ module.exports = class StripeWebhookService { return; } // Subscription is for a different product - ignore. - if (this._stripePlansService.getProduct().id !== subscription.plan.product) { + const product = await this._productRepository.get({ + stripe_product_id: subscription.plan.product + }); + if (!product) { return; } + // Could not find the member, which we need in order to insert an payment event. throw new errors.NotFoundError({ message: `No member found for customer ${subscription.customer}` diff --git a/ghost/members-api/test/unit/lib/services/stripe-webhook.test.js b/ghost/members-api/test/unit/lib/services/stripe-webhook.test.js index d9eb0d29d0..f571f412b8 100644 --- a/ghost/members-api/test/unit/lib/services/stripe-webhook.test.js +++ b/ghost/members-api/test/unit/lib/services/stripe-webhook.test.js @@ -2,8 +2,8 @@ const {describe, it} = require('mocha'); const should = require('should'); const sinon = require('sinon'); const StripeAPIService = require('../../../../lib/services/stripe-api'); -const StripePlansService = require('../../../../lib/services/stripe-plans'); const StripeWebhookService = require('../../../../lib/services/stripe-webhook'); +const ProductRepository = require('../../../../lib/repositories/product'); const MemberRepository = require('../../../../lib/repositories/member'); function mock(Class) { @@ -15,7 +15,7 @@ describe('StripeWebhookService', function () { it('Should throw a 404 error when a member is not found for a valid Ghost Members invoice', async function () { const stripeWebhookService = new StripeWebhookService({ stripeAPIService: mock(StripeAPIService), - stripePlansService: mock(StripePlansService), + productRepository: mock(ProductRepository), memberRepository: mock(MemberRepository) }); @@ -28,7 +28,7 @@ describe('StripeWebhookService', function () { stripeWebhookService._memberRepository.get.resolves(null); - stripeWebhookService._stripePlansService.getProduct.returns({ + stripeWebhookService._productRepository.get.resolves({ id: 'product_id' });