Skip to content

[pull] main from baptisteArno:main #288

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

Merged
merged 2 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion apps/landing-page/content/terms-of-service.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ Payment is processed automatically using the payment method you provided. If a p

You can [upgrade or downgrade](https://docs.typebot.io/workspace/subscription) at any time within your account settings.

## Refund Policy

We offer a 14-day refund period from your first payment. If you're not satisfied with our service during this period, we'll provide a full refund, no questions asked. To request a refund, please contact us at [email protected] within 14 days of your initial payment.

Refunds are only available for first-time payments to new accounts. Subsequent subscription renewals, upgrades, or additional purchases are not eligible for refunds under this policy, but you can cancel at any time to avoid future charges.

## Cancellation and Termination

You are solely responsible for properly canceling your account. An email to cancel your account is not considered cancellation. You can find instructions for how to cancel your account [here](https://docs.typebot.io/workspace/subscription#cancel-plan). We provide a simple no-questions-asked cancellation link.
Expand Down Expand Up @@ -111,4 +117,4 @@ We may modify these terms with 30 days notice. Continued use after changes indic

If you have a question about any of the Terms of Service, please [contact us](mailto:[email protected]).

Last updated: July 16, 2025
Last updated: July 21, 2025
116 changes: 48 additions & 68 deletions packages/billing/src/api/webhookHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,79 +176,59 @@ export const webhookHandler = async (
})),
);

if (subscription.status !== "past_due" || existingWorkspace.isPastDue)
return res.send({
message: "Not newly past due, skipping.",
if (
subscription.status === "past_due" &&
previous &&
previous.status !== "past_due" &&
!existingWorkspace.isPastDue
) {
await prisma.workspace.updateMany({
where: {
id: existingWorkspace.id,
},
data: {
isPastDue: true,
},
});

await prisma.workspace.updateMany({
where: {
id: existingWorkspace.id,
},
data: {
isPastDue: true,
},
});

await trackEvents(
existingWorkspace.members.map((m) => ({
name: "Workspace past due",
workspaceId: existingWorkspace.id,
userId: m.userId,
})),
);
return res.send({ message: "Workspace set to past due." });
}
case "invoice.paid": {
const invoice = event.data.object as Stripe.Invoice;
const workspace = await prisma.workspace.findFirst({
where: {
stripeId: invoice.customer as string,
},
select: {
isPastDue: true,
},
});
if (!workspace?.isPastDue)
return res.send({ message: "Workspace not past_due, skipping." });
const outstandingInvoices = await stripe.invoices.list({
customer: invoice.customer as string,
status: "open",
});
const outstandingInvoicesWithAdditionalUsageCosts =
outstandingInvoices.data.filter(
(invoice) => invoice.amount_due > prices["PRO"] * 100,
await trackEvents(
existingWorkspace.members.map((m) => ({
name: "Workspace past due",
workspaceId: existingWorkspace.id,
userId: m.userId,
})),
);
if (outstandingInvoicesWithAdditionalUsageCosts.length > 0)
return res.send({
message: "Workspace has outstanding invoices, skipping.",
});
const updatedWorkspace = await prisma.workspace.update({
where: {
stripeId: invoice.customer as string,
},
data: {
isPastDue: false,
},
select: {
id: true,
members: {
select: { userId: true },
where: {
role: WorkspaceRole.ADMIN,
},
return res.send({ message: "Workspace set to past due." });
}

if (
subscription.status === "active" &&
previous &&
previous.status === "past_due" &&
existingWorkspace.isPastDue
) {
await prisma.workspace.updateMany({
where: {
id: existingWorkspace.id,
},
},
});
await trackEvents(
updatedWorkspace.members.map((m) => ({
name: "Workspace past due status removed",
workspaceId: updatedWorkspace.id,
userId: m.userId,
})),
);
return res.send({ message: "Workspace was regulated" });
data: {
isPastDue: false,
},
});

await trackEvents(
existingWorkspace.members.map((m) => ({
name: "Workspace past due status removed",
workspaceId: existingWorkspace.id,
userId: m.userId,
})),
);
return res.send({ message: "Workspace past due status removed." });
}

return res.send({ message: "Nothing to do" });
}

case "customer.subscription.deleted": {
const subscription = event.data.object as Stripe.Subscription;
const { data } = await stripe.subscriptions.list({
Expand Down
Loading