Closed tomzacchia closed 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) |
@mimi-ta
@mimi-ta i made some changes based on your review
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.
Sun Jan 01 2023 08:00:00 GMT+0000
unix timestamp is1672560000
. Notice that the unix timestamp has no information with regards to timezone so if someone in Vancouverconsole.log(new Date(1672560000))
they'll seeSun Jan 01 2023 00:00:00 GMT-0800 (Pacific Standard Time)
, whereas someone in Montreal would seeSun Jan 01 2023 00:03:00 GMT-0500 (Eastern Standard Time)
. This is important to know because when we want to verify if the user has a valid subscription we need to use a Unix timestamp, in seconds, and our logic would work regardless of which timezone the server in.paid
user has paid their invoicetrialing
user is trialing servicespast_due
when one billing cycle ends and another begins, Stripe will create an invoice and attempt to charge the user's payment card on file. If they are unable to, this is when the subscription's status ispast_due
canceled
either the user has canceled their subscription or Stripe canceled because multiple attempts to charge the user failedTo 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 callstripeService.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. Instripe.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.