Maple-GPT-Software / excel-gpt-3-monorepo

https://excel-gpt-monorepo.vercel.app
1 stars 0 forks source link

Server feat/11 stripe subscription #19

Closed tomzacchia closed 1 year ago

tomzacchia commented 1 year ago

Issue

Addresses back-end items in issue #11 - subscriptions

Type of change

Description

The PR is 700 lines code, maybe 20-30% of which are comments. Github's calculation of the diff is whack

We use Stripe to manage everything related to payments; storing sensitive payment information, collecting taxes (to be included after incorporating), managing free-trials and subscriptions. Stripe does all the heavy lifting for all the aforementioned items. Our server acts as the bridge between Stripe and our database. Since we only do subscription based pricing, e.g premium, teams (eventually). The two critical pieces of information that we need to keep track of are: 1) current period end and 2) status.

To understand what I was trying to do, you can refer to the following diagrams: Stripe Checkout and Webhooks.


Webhooks

Stripe uses webhooks to notify subscribers when an asynchronous event has taken place, for example a customer was created or a subscription had been created/paid for. In App.ts there is some repetition, we call stripeService.updateSubscription in three different switch cases but in the future we can do different things depending on the kind of event that is recevied, for example send a user an email after they sign up for any subscription type. In stripe.service we don't need to send the updated document, however we do want failed updates to be logged by winston.

Webhooks aside there are 3 payment related routes: 1)/trial for creating a Stripe customer 2) /cancel-subscription/:id cancels a subscription by ID 3) /subscription-session makes a call to Stripe to create a checkout session, which returns re-direct URL. The client app re-directs the user to a checkout page hosted by Stripe. It looks like the following.


How do grant access to our services

As previously mentioned we keep track of when the user's current bill ends and the status of their subscription. Say the user signs up for a monthly premium subscription on the 1st of Feb 2023, since we bill on monthly basis the user's current period end will be the 28th of February 2023. For APIs which require active subscriptions (including trials) there's a subscriptionCheck middleware that checks if the user is permitted to access such resources. The cases in which we grant access are documented in the unit test, subscriptionCheck.test.ts.

In short the logic checks if the UNIX timestamp for present time, when the request is made, is before the UNIX timestamp of current period end. In general user's with ["trialing" | "paid" | "canceled"] are permitted to access APIs that require subscriptions. When users cancel their subscription we end the subscription immediately but we bill at the beginning of the billing period, e.g 1 Feb 2023, so we still allow access until the end of their billing period (to be nice? 😉 ).

How to Test your Changes?

I created this test plan, which mirrors the unit test, and uses Stripe test clock to verify that the user's subscription status was being updated. The test clock also allows us to "advance" time, so we can test things like invalid payment or free trial expires.

Screenshot 2023-03-01 at 8 39 03 PM

vercel[bot] commented 1 year ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated
excel-gpt-monorepo ✅ Ready (Inspect) Visit Preview 💬 Add your feedback Mar 8, 2023 at 0:45AM (UTC)
tomzacchia commented 1 year ago

@mimi-ta

tomzacchia commented 1 year ago

@mimi-ta i made some changes based on your review