refs https://github.com/TryGhost/Team/issues/1526
We weren't using the `req.body.customerEmail` to load a member and
check their existing tiers, this meant that existing members which
were signed out and attempted to create a stripe checkout session were
able to.
refs https://ghost.slack.com/archives/C02G9E68C/p1652980792270029
When bulk unsubscribing members, the number of deleted newsletter relations are returned instead of the number of members with newsletters that were cleared. This update deletes newsletter relations on member_id, so we can return the count of members instead of newsletter relations that were deleted.
Tests in https://github.com/TryGhost/Ghost/pull/14871
- In case of an offer id present in stripe checkout session, the cadence and tier id values can be null
- this fixes the invalid 400 thrown on missing cadence value while creating stripe checkout session for offer
no issue
- Setting a dedicated source for imported members was already done with 455778662c
- This unifies the same source but keeps the usage of context setting on init alive
refs https://github.com/TryGhost/Team/issues/1577
The call to `edit` was not loading the newsletter relations which is needed
by the serializer used by the webhooks service.
Co-authored-by: Fabien "egg" O'Carroll <fabien@allou.is>
no issue
Using a designated source for members being added within the `importer` context will better describe the source in our members event table. It's more consistent with the usage of the other possible sources.
no issue
When importing members, the members-importer isn't aware of the context and therefore falls back to use `member` as a source in members event table. This makes it impossible to determine imported members from others.
- Added an `context` property to the options in the members-importer constructor
- Checked for `importer` context when creating member events and assigned the source `admin` to it
refs https://github.com/TryGhost/Team/issues/1478
- When creating or editing a member, we'll add the newsletter ids to the subscribe events
- When susbcribing to multiple newsletters, we'll create multiple subscribe events
- When removing newsletters from a member, we'll create one or more subscribe events
- Tests in https://github.com/TryGhost/Ghost/pull/14579
refs https://github.com/TryGhost/Team/issues/1520
- Instead of doing the matching of the offers and subscriptions by looking at the offer redemptions, we can now look at the offer_id from subscriptions.
- This also fixes an issue where we don't attach the offer object to subscriptions in the members' browse method
- Updated browse behaviour to match the read behaviour of members (product relation needs to get loaded because it is missing in member.products if the subscription is expired).
Tests in https://github.com/TryGhost/Ghost/pull/14515
refs https://github.com/TryGhost/Team/issues/1519
- Removed offer metadata again from offer (added in one of the previous commits)
- Added `getByStripeCouponId` method in offer repository (required to find an offer based on the stripe_coupon_id)
- Match discounts from Stripe based on the stripe_coupon_id instead of metadata
refs https://github.com/TryGhost/Team/issues/1519
- Added offer repository dependency to member repository (offerAPI didn't work because it creates a new transaction that resulted in a deadlock during tests)
- Store the offer id from the Stripe subscription metadata in the subscription (only if the discount is still active)
- Also added the offer id to the metadata for a Stripe coupon, this will make adding and removing coupons a bit more foolproof
- Prefer the usage of the offer metadata from a coupon if it is present
- When no discount is applied to a subscription, it always sets the offer id to null, even when the metadata still contains the offer
- The offer_id remains stored when a subscription is canceled/expired
refs https://github.com/TryGhost/Team/issues/1469
Previously, members were subscribed to all available newsletters by default when added. This change updates the default newsletters subscription for member to take into account newsletter preferences for auto opt-in as well as visibility.
refs: https://github.com/TryGhost/Toolbox/issues/293
Things needed to create this:
* MemberSubscriptionEvent now has an import source
* Importer now creates events with this type
* Verification trigger logic changed to use 30 day window of imports
* Updated member mrr_delta calculation to use stored mrr
refs https://github.com/TryGhost/Team/issues/1456
Simplifies the calculation of MRR deltas, which will make it easier to update MRR to include offers and cancellations in the future.
* Adjusted MRR and MRR delta calculation to consider "forever" duration offers
refs https://github.com/TryGhost/Team/issues/1451
Uses the discount information from Stripe to calculate the MRR (this was the easiest way to include it + also supports manually created discounts from users)
refs https://github.com/TryGhost/Team/issues/1490
With multiple newsletters, free members can choose their newsletter subscription preference while signing up.
This change -
- includes newsletters data in magic link token creation
- attaches newsletter data to new members created via magic link
refs https://github.com/TryGhost/Team/issues/1456
- Sets the `mrr` column correctly when updating a subscription
- We can use this value in the future to have an improved calculation of mrr_delta, but we first need to have the migration in place
- Updated missing cancelled -> canceled
refs https://github.com/TryGhost/Team/issues/1469
When a new member signs up on the site, by default they should get subscribed to all newsletters. A new member can get added via different ways (stripe webhook, admin add, free signup), so this change updates the base member repository which gets used irrespective of how member is added to ensure default newsletters are always included for new member.
If a member already has a custom newsletters list attached, we don't change anything.
refs https://github.com/TryGhost/Team/issues/1469
With multiple newsletters, members can now have one or more newsletter subscriptions that is attached to them. This change updates the member BREAD service to handle attaching newsletter data to member, based on the newsletter flag.
- if newsletter flag is disabled, add/edit methods delete any newsletter data attached to member
- sets `newsletters` as a default relation for read/browse methods so a member always has newsletter data attached to them
no issue
- When a new member is added via the API, with a stripe_customer_id, the member bread service is passed also with a default option: `withRelated: ['labels']`.
- This option is passed along to the member repository, and further and is also passed when loading relations that don't have a relationship called 'labels'.
- This results in a `labels is not defined on the model` error when you try to create a new member with a stripe customer id.
- Test that found this issue will be added to the Ghost repo.
refs https://github.com/TryGhost/Team/issues/1141
- when a member had canceled subscriptions the check we have to match products to subscriptions to determine whether to insert the hardcoded complimentary subscription was incorrectly matching against the canceled subscriptions
- updated to match only active subscriptions
refs https://github.com/TryGhost/Team/issues/1141
- The goal is to retrieve the product name for canceled subscriptions
- The property is located at `member.subscriptions.price.product.name`
- We can't easily get the full product as products are retrieved using a join through `members_products`, and there is only a `members_products` row when the subscription is active
refs https://github.com/TryGhost/Team/issues/1387
First, this default value didn't make sense as it was written when we
had a boolean visible column, second, we don't need to add defaults here
- this implementation is super tied to the models anyway, so we may as
well rely on the model defaults - if we do pull it out similar to
Offers, then it may make sense to add a default there.
We also update the JSDoc to match the updated data structure.
refs: 23b383bedf
- @tryghost/error constructors take an object, not a string - the expectation is that message, context & help should all be set
- This does the bare minimum and just ensures message is set correctly
refs https://github.com/TryGhost/Team/issues/1322
We no longer restart the Members service based on the Stripe service
being updated, which meant that if it was initially configured with
missing URL's and later Stripe connected, it would not get the new
config until a server restart. This moves the last of Stripe config into
the Stripe service, so that all things concerning Stripe can be handled
in one place and updated together.
refs https://github.com/TryGhost/Team/issues/1319
Rather than allowing our code to attempt to speak with Stripe and error
there, we opt to fail fast and throw validation errors so that our API
will respond with a 422, the existing pattern for validation errors.