mollie / mollie-api-node

Official Mollie API client for Node
http://www.mollie.com
BSD 3-Clause "New" or "Revised" License
231 stars 63 forks source link

Pro rata subscription updates #276

Closed nemdo closed 2 years ago

nemdo commented 2 years ago

I am trying to figure out how to correctly update a subscription with the Subscription Update API and I think that it is not possible.

Nowadays, any SaaS business has multiple subscription plans i.e premium/pro/enterprise that is billed monthly/annually which gives us 6 different plans. When upgrading, users expect to only pay the pro rata difference for the rest of the subscription period (interval) and, when downgrading, expect to keep the advantages of the better plan for the rest of the subscription period, otherwise it would be nothing more than pure theft! In general, avoiding criminal prosecution from users is considered a good UX.

For instance, this is automatically integrated in Stripe. So I played with Mollie's customers_subscriptions.update and it feels like the current parameters do not allow to create such a logic or am I missing something?

For now, the only solution I see for upgrades:

  1. Cancel subscription
    • Mandate remains valid
  2. Create payment
    • Specify sequenceType = "recurring"
      • Because "oneoff" requires checkout and we still have a valid mandate
    • Provide customerId or current mandateId
    • Pro rata amount to pay today:
      • daysLeft = nextPaymentDate_T - (dateNow - nextPaymentDate_T-1)
      • amount = (daysLeft / interval) * (newSubAmount - oldSubAmount)
    • Webhook listens today, upgrades user's plan role in db and (below) creates a new subscription
  3. Create new subscription
    • startDate = old's nextPaymentDate_T

For downgrades: Note: more complicated because user's plan role needs to remain the same until the end of the current period which means that when the new subscrition starts, something needs to trigger the downgrade of user's plan role, but ONLY ONCE.

  1. Update the subscription with customers_subscriptions.update
    • Add specific metadata to listen for the first subscription payment in the webhook
  2. Automatically update the subscription again in the webhook the day of the first payment
    • Update user's role in db and modify metadata to listen for future standard subscription payment

Someone else had the same concerns 5 years ago here, any updates? It would be really nice to add the adequate parameters and returned responses to the Subscription Update API to be able to configure all that easily.

EDIT: I implemented it and it looks good

Pimm commented 2 years ago

Thanks for the issue.

This is currently the responsibility of the merchant; Mollie doesn't support this functionality on their end. It is somewhere on the backlog, but buried so deep that you shouldn't be holding your breath for it.

There is a variety of ways to implement a feature like this, with no correct way that will satisfy everyone.

What you've described, is a pro rata upgrade, but an at-the-end-of-the-period downgrade (as opposed to a pro rata downgrade, with a partial refund of the most recent payment). You've included a calculation based on days, resulting in customers getting a slightly better or worse deal depending on whether they upgrade early in the morning or late at night. And when I see the concept of days mentioned, my engineering brain immediately asks "days according to whom?" I would guess you went with the time zone of the merchant. This all sounds very sensible to me, but others might have different ideas of how this should work.

If you need this feature in your product, you will have to implement it yourself. A hint: the Subscriptions API is designed to make it easier to deal with recurring payments. If you need more fine-grained control, you might find that it complicates matters rather than simplifying them, in which case you should consider using the Payments API and Mandates API directly instead.

If implementing something like this isn't an option, you can consider using a subscription provider for whom subscriptions is their core product.

A minor note: please start using customerSubscriptions: this will reduce friction later as customers_subscriptions will be removed at some point.

anbraten commented 2 years ago

We are currently trying to implement a similar model. Pretty interesting to see your thoughts on this 😃

One question we are trying to solve atm is how to do the first payment / payment method verification as we plan to do post-paid payments. One idea was to charge 1€ and add it as credit to the customer model.

We published our still WIP service as OSS, if you are interested in it: https://github.com/geprog/gringotts

Pimm commented 2 years ago

One question we are trying to solve atm is how to do the first payment / payment method verification as we plan to do post-paid payments. One idea was to charge 1€ and add it as credit to the customer model.

If you want to charge customers at will, you will indeed have to create a first payment of some amount. See recurring payments. If setting the amount for that first payment to €1 and then adding that to the credit of your customer fits your product, then that sounds like a great way to do it.