Skip to content
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
6 changes: 4 additions & 2 deletions apps/code/src/app/dashboard/components/DevPassInvoices.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,14 @@ function RefundButton({ invoice }: { invoice: Invoice }) {
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
{isResetPass ? "Refund this Reset Pass?" : "Refund this payment?"}
{isResetPass
? "Refund this Reset Pass?"
: "Refund and cancel your DevPass?"}
</AlertDialogTitle>
<AlertDialogDescription>
{isResetPass
? `${formatAmount(invoice.amount, invoice.currency)} will be refunded to your payment method and the unused pass removed from your passport. Your DevPass plan is not affected. This cannot be undone.`
: `${formatAmount(invoice.amount, invoice.currency)} will be refunded to your payment method and your DevPass will be cancelled immediately. This cannot be undone.`}
: `Refunding cancels your subscription completely: ${formatAmount(invoice.amount, invoice.currency)} goes back to your payment method and your DevPass ends right away — not at the end of the billing period — so the rest of this cycle's credits are lost. To use DevPass again you would have to subscribe from scratch. This cannot be undone.`}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
Expand Down
21 changes: 13 additions & 8 deletions apps/playground/src/components/pricing/chat-billing-history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,21 @@ function RefundButton({
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Refund this payment?</AlertDialogTitle>
<AlertDialogTitle>
{isPlanPayment(transaction.type)
? "Refund and cancel your membership?"
: "Refund this payment?"}
</AlertDialogTitle>
<AlertDialogDescription>
{formatAmount(transaction.amount, transaction.currency)} will be
refunded to your payment method.{" "}
{isPlanPayment(transaction.type)
? "Your chat plan will be cancelled immediately. "
: "The purchased credits will be removed from your balance. "}
This cannot be undone.
? `Refunding cancels your Lounge membership completely: ${formatAmount(transaction.amount, transaction.currency)} goes back to your payment method and your access ends right away — not at the end of the billing period — so the rest of this cycle's credits are lost. To keep using the Lounge you would have to subscribe again. This cannot be undone.`
: `${formatAmount(transaction.amount, transaction.currency)} will be refunded to your payment method. The purchased credits will be removed from your balance. This cannot be undone.`}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogCancel>
{isPlanPayment(transaction.type) ? "Keep my membership" : "Cancel"}
</AlertDialogCancel>
<AlertDialogAction
onClick={() =>
refundMutation.mutate({
Expand All @@ -266,7 +269,9 @@ function RefundButton({
})
}
>
Request refund
{isPlanPayment(transaction.type)
? "Refund and cancel"
: "Request refund"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
Expand Down
56 changes: 46 additions & 10 deletions apps/ui/src/components/billing/transactions-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ interface Transaction {
| "credit_gift"
| "subscription_start"
| "subscription_cancel"
| "subscription_end";
| "subscription_end"
| "dev_plan_start"
| "dev_plan_renewal"
| "dev_plan_reset_pass"
| "chat_plan_start"
| "chat_plan_renewal";
creditAmount: string | null;
amount: string | null;
status: "pending" | "completed" | "failed";
Expand All @@ -83,6 +88,17 @@ const REFUND_INELIGIBILITY_COPY: Record<
pass_already_used: "This Reset Pass has already been redeemed",
};

// Refunding a plan payment does not just return the money: the webhook cancels
// the Stripe subscription outright, so the dialog has to say so.
function isPlanPayment(type: Transaction["type"]): boolean {
return (
type === "dev_plan_start" ||
type === "dev_plan_renewal" ||
type === "chat_plan_start" ||
type === "chat_plan_renewal"
);
}

function RefundButton({
orgId,
transaction,
Expand Down Expand Up @@ -114,8 +130,9 @@ function RefundButton({
}
toast({
title: "Refund processing",
description:
"Your refund has been submitted and will appear in your transaction history shortly.",
description: isPlanPayment(transaction.type)
? "Your subscription has been cancelled and the refund will appear in your transaction history shortly."
: "Your refund has been submitted and will appear in your transaction history shortly.",
});
router.refresh();
} catch {
Expand Down Expand Up @@ -164,18 +181,37 @@ function RefundButton({
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Refund this purchase?</AlertDialogTitle>
<AlertDialogTitle>
{isPlanPayment(transaction.type)
? "Refund and cancel your subscription?"
: "Refund this purchase?"}
</AlertDialogTitle>
<AlertDialogDescription>
${Number(transaction.amount ?? 0).toFixed(2)} will be refunded to
your original payment method and{" "}
{Number(transaction.creditAmount ?? 0).toFixed(2)} credits will be
removed from your balance. This cannot be undone.
{isPlanPayment(transaction.type)
? `Refunding cancels your subscription completely: $${Number(
transaction.amount ?? 0,
).toFixed(
2,
)} goes back to your original payment method and the plan ends right away — not at the end of the billing period — so the rest of this cycle's credits are lost. To use it again you would have to subscribe from scratch. This cannot be undone.`
: transaction.type === "dev_plan_reset_pass"
? `$${Number(transaction.amount ?? 0).toFixed(2)} will be refunded to your original payment method and the unused Reset Pass removed from your account. Your plan is not affected. This cannot be undone.`
: `$${Number(transaction.amount ?? 0).toFixed(2)} will be refunded to your original payment method and ${Number(
transaction.creditAmount ?? 0,
).toFixed(
2,
)} credits will be removed from your balance. This cannot be undone.`}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogCancel>
{isPlanPayment(transaction.type)
? "Keep my subscription"
: "Cancel"}
</AlertDialogCancel>
<AlertDialogAction onClick={handleRefund}>
Request refund
{isPlanPayment(transaction.type)
? "Refund and cancel"
: "Request refund"}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
Expand Down
Loading