-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Stripe and payment processing improvements #493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| import type { SubscriptionStatus } from '../plans'; | ||
| import { PaymentPlanId } from '../plans'; | ||
|
|
||
| export async function updateUserStripePaymentDetails( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just old updateUserStripePaymentDetails from stripe/paymentDetails, but I've split it up into two separate functions which correspond to two different actions it does.
| import Stripe from 'stripe'; | ||
| import { requireNodeEnvVar } from '../../server/utils'; | ||
|
|
||
| export const stripe = new Stripe(requireNodeEnvVar('STRIPE_API_KEY'), { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having it named stripe makes it easy to confuse with the Stripe namespace often imported everywhere.
And it is a client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Looks great. Just a couple comments + we need to update docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
- Align with changes coming in wasp-lang#493
|
Updated docs. Looks like we didn't generate llms text for previous versions so there is some extra. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. Merge it!
…ments # Conflicts: # opensaas-sh/app_diff/package-lock.json.diff
Fixes #487
The idea of this PR is to improve the current Stripe payment processing system.
However some of the changes touch a wider concepts so it also changes files outside of
payments/stripe.Main behavioral change is that we now generate
Stripe.Invoicefor one-time payments.We didn't do that before (in older Stripe API versions it wasn't possible), so we had to handle one-time payments separately from subscriptions. Now this is unified under
invoice.paidevent.Another side-effect of above is that users who only use one-time payments also have invoices.
So it felt wrong that accessing the Stripe billing portal was only possible to users with active subscriptions.
The billing portal allows you to:
So it should be accessible to everyone.
Changes to
AccountPage.tsxare related to that change.I've also made it so we have create customer specific billing portals.
This can be seen in
stripe/paymentProcessor.ts'sfetchCustomerPortalUrl.The change here is that users are automatically logged in into their Stripe customer account when they open the link:
Screen.Recording.2025-08-11.at.13.38.02.mov
One bigger change is that I removed all parsing inside of
stripe/webhookPayload.ts. This is because Stripe already verifies the event data itself. This is enforced by its SDK. No need to parse twice. We also lost type information by using custom parsing interfaces.The rest is not really behavioral changes.
Just improvements to old code.
There is also some noise because we updated
diffsfor some old files nobody updated the diff for.Changes:
fetchStripeCustomeremailis not a unique field forStripe.CustomerStripe.Customerper 1User.emailbut that is enforced by our own application logicStripe.Customer.idunderUser.paymentProcessorUserIdStripe.Customerby itsid, which is unique, rather by itsemailensureStripeCustomerstripePaymentProcessor.createCheckoutSessionStripe.CustomerStripe.Checkout.SessionUsertoStripe.CustomerStripe.Customer(rather than fetching), and we error on creating aStripe.Checkout.Session, we won’t connectUserto the newly createdStripe.CustomerStripe.Customersince we fetch it byemailStripe.CustomertoUserbefore we create aStripe.Checkout.SessionpaymentDetails.tsUserentity, let's mention the user in the namepaymentDetails.ts->userPaymentDetails.tsstripePaymentProcessor.fetchCustomerPortalUrlSTRIPE_CUSTOMER_PORTAL_URLand then we fetch it though server on the client.stripeClient.billingPortal.sessions.create, which creates a billing portal URL for that specific customerstripeClientnow, rather than using predefined URLSTRIPE_CUSTOMER_PORTAL_URLstripe/webhookPayload.tszodschemas.stripeClient.webhooks.constructEvent.zodschemas.I deleted the Stripe
webhookPayload.ts.Payment details auditing problems
webhook.tsinvoice.paideventcheckout.session.completedeventsCheckoutPage.tsxCheckoutPage.tsx->CheckoutResultPage.tsxAccountPage.tsxUser.paymentProcessorIdshould beOther than mentioned changes I've also clean up the types and general logic to be clearer.