diff --git a/apps/licenses/src/index.ts b/apps/licenses/src/index.ts index 163cfa58b..12d29dc3f 100644 --- a/apps/licenses/src/index.ts +++ b/apps/licenses/src/index.ts @@ -34,8 +34,6 @@ router.use( }), ); -console.log(process.env.DATABASE_URL); - const validateSchema = z.object({ licenseKey: z.string(), serverIp: z.string(), @@ -161,6 +159,7 @@ router.post("/stripe/webhook", async (c) => { "invoice.payment_succeeded", "invoice.payment_failed", "customer.subscription.deleted", + "invoice.paid", ]; if (!allowedEvents.includes(event.type)) { @@ -169,58 +168,6 @@ router.post("/stripe/webhook", async (c) => { try { switch (event.type) { - case "checkout.session.completed": { - const session = event.data.object as Stripe.Checkout.Session; - - const customerResponse = await stripe.customers.retrieve( - session.customer as string, - ); - - if (customerResponse.deleted) { - throw new Error("Customer was deleted"); - } - - const lineItems = await stripe.checkout.sessions.listLineItems( - session.id, - ); - const priceId = lineItems.data[0].price?.id; - - const { type, billingType } = getLicenseTypeFromPriceId(priceId!); - - const license = await createLicense({ - productId: session.id, - type, - billingType, - email: session.customer_details?.email!, - stripeCustomerId: customerResponse.id, - stripeSubscriptionId: session.subscription as string, - }); - - console.log("License created", license); - - const features = getLicenseFeatures(type); - console.log("Features", features); - const emailHtml = await render( - LicenseEmail({ - customerName: customerResponse.name || "Customer", - licenseKey: license.licenseKey, - productName: `Dokploy Self Hosted ${type}`, - // TODO: Add expiration date - expirationDate: new Date(), - features: features, - }), - ); - - await transporter.sendMail({ - from: process.env.SMTP_FROM_ADDRESS, - to: license.email, - subject: "Your Dokploy License Key", - html: emailHtml, - }); - - break; - } - case "customer.subscription.updated": { const subscription = event.data.object as Stripe.Subscription; @@ -231,6 +178,55 @@ router.post("/stripe/webhook", async (c) => { if (subscription.status !== "active" || customerResponse.deleted) { await deactivateLicense(subscription.id); } + break; + } + + case "invoice.paid": { + const invoice = event.data.object as Stripe.Invoice; + + if (!invoice.subscription) break; + + if (invoice.billing_reason === "subscription_create") { + const customerResponse = await stripe.customers.retrieve( + invoice.customer as string, + ); + + if (customerResponse.deleted) { + throw new Error("Customer was deleted"); + } + + const subscriptionId = invoice.subscription as string; + const subscription = + await stripe.subscriptions.retrieve(subscriptionId); + const priceId = subscription.items.data[0].price.id; + const { type, billingType } = getLicenseTypeFromPriceId(priceId); + + const license = await createLicense({ + productId: subscriptionId, + type, + billingType, + email: customerResponse.email!, + stripeCustomerId: customerResponse.id, + stripeSubscriptionId: subscriptionId, + }); + + const features = getLicenseFeatures(type); + const emailHtml = await render( + LicenseEmail({ + customerName: customerResponse.name || "Customer", + licenseKey: license.licenseKey, + productName: `Dokploy Self Hosted ${type}`, + features: features, + }), + ); + + await transporter.sendMail({ + from: process.env.SMTP_FROM_ADDRESS, + to: license.email, + subject: "Your Dokploy License Key ", + html: emailHtml, + }); + } break; } diff --git a/apps/licenses/templates/emails/license-email.tsx b/apps/licenses/templates/emails/license-email.tsx index 6a8337aae..663297504 100644 --- a/apps/licenses/templates/emails/license-email.tsx +++ b/apps/licenses/templates/emails/license-email.tsx @@ -18,7 +18,6 @@ interface LicenseEmailProps { customerName: string; licenseKey: string; productName: string; - expirationDate: Date; features: string[]; } @@ -28,15 +27,8 @@ export const LicenseEmail = ({ customerName = "John Doe", licenseKey = "1234567890", productName = "Dokploy", - expirationDate = new Date(), features = ["Feature 1", "Feature 2", "Feature 3"], }: LicenseEmailProps): React.ReactElement => { - const formattedDate = expirationDate.toLocaleDateString("en-US", { - year: "numeric", - month: "long", - day: "numeric", - }); - return ( @@ -69,12 +61,6 @@ export const LicenseEmail = ({ {licenseKey} -
- - 🗓️ Next billing date: {formattedDate} - -
-
🎉 Your Premium Features