Copy overhaul + qr designs
This commit is contained in:
@@ -35,7 +35,16 @@ export async function POST(request: NextRequest) {
|
||||
}
|
||||
|
||||
// Get plan and billing interval from request
|
||||
const { plan, billingInterval = 'month' } = await request.json();
|
||||
const { plan, billingInterval = 'month', returnPath } = await request.json();
|
||||
|
||||
// Where to send the user after checkout. Used by the in-app upgrade modal so
|
||||
// people land back on the thing they were building instead of the dashboard.
|
||||
const safeReturnPath =
|
||||
typeof returnPath === 'string' &&
|
||||
returnPath.startsWith('/') &&
|
||||
!returnPath.startsWith('//')
|
||||
? returnPath
|
||||
: null;
|
||||
|
||||
if (!plan || !['PRO', 'BUSINESS'].includes(plan)) {
|
||||
return NextResponse.json(
|
||||
@@ -114,8 +123,12 @@ export async function POST(request: NextRequest) {
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
success_url: `${appUrl}/dashboard?success=true&session_id={CHECKOUT_SESSION_ID}`,
|
||||
cancel_url: `${appUrl}/pricing?canceled=true`,
|
||||
success_url: safeReturnPath
|
||||
? `${appUrl}${safeReturnPath}${safeReturnPath.includes('?') ? '&' : '?'}success=true&session_id={CHECKOUT_SESSION_ID}`
|
||||
: `${appUrl}/dashboard?success=true&session_id={CHECKOUT_SESSION_ID}`,
|
||||
cancel_url: safeReturnPath
|
||||
? `${appUrl}${safeReturnPath}${safeReturnPath.includes('?') ? '&' : '?'}canceled=true`
|
||||
: `${appUrl}/pricing?canceled=true`,
|
||||
metadata: {
|
||||
userId: user.id,
|
||||
plan,
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { headers } from 'next/headers';
|
||||
import { getPlanFromStripePriceId, stripe } from '@/lib/stripe';
|
||||
import { db } from '@/lib/db';
|
||||
import Stripe from 'stripe';
|
||||
import { sendConversionEvent } from '@/lib/metaConversions';
|
||||
import { scoreUserLifecycle } from '@/lib/revops-server';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { headers } from 'next/headers';
|
||||
import { getPlanFromStripePriceId, stripe } from '@/lib/stripe';
|
||||
import { db } from '@/lib/db';
|
||||
import Stripe from 'stripe';
|
||||
import { sendConversionEvent } from '@/lib/metaConversions';
|
||||
import { scoreUserLifecycle } from '@/lib/revops-server';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const body = await request.text();
|
||||
@@ -51,21 +51,21 @@ export async function POST(request: NextRequest) {
|
||||
? new Date(periodEndTimestamp * 1000)
|
||||
: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
|
||||
|
||||
const updatedUser = await db.user.update({
|
||||
where: {
|
||||
stripeCustomerId: session.customer as string,
|
||||
const updatedUser = await db.user.update({
|
||||
where: {
|
||||
stripeCustomerId: session.customer as string,
|
||||
},
|
||||
data: {
|
||||
stripeSubscriptionId: subscription.id,
|
||||
stripePriceId: subscription.items.data[0].price.id,
|
||||
stripeCurrentPeriodEnd: currentPeriodEnd,
|
||||
plan: (session.metadata?.plan || 'FREE') as any,
|
||||
},
|
||||
});
|
||||
|
||||
await scoreUserLifecycle(updatedUser.id, 'subscription_created');
|
||||
},
|
||||
});
|
||||
|
||||
// Meta CAPI — Purchase event
|
||||
await scoreUserLifecycle(updatedUser.id, 'subscription_created');
|
||||
|
||||
// Meta CAPI - Purchase event
|
||||
const amountCents = session.amount_total ?? 0;
|
||||
sendConversionEvent({
|
||||
eventName: 'Purchase',
|
||||
@@ -95,47 +95,47 @@ export async function POST(request: NextRequest) {
|
||||
? new Date(periodEndTimestamp * 1000)
|
||||
: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);
|
||||
|
||||
await db.user.update({
|
||||
where: {
|
||||
stripeSubscriptionId: subscription.id,
|
||||
},
|
||||
data: {
|
||||
stripePriceId: subscription.items.data[0].price.id,
|
||||
stripeCurrentPeriodEnd: currentPeriodEnd,
|
||||
plan: getPlanFromStripePriceId(subscription.items.data[0].price.id) ?? undefined,
|
||||
},
|
||||
});
|
||||
const updated = await db.user.findUnique({
|
||||
where: { stripeSubscriptionId: subscription.id },
|
||||
select: { id: true },
|
||||
});
|
||||
if (updated?.id) {
|
||||
await scoreUserLifecycle(
|
||||
updated.id,
|
||||
subscription.cancel_at_period_end ? 'subscription_canceled_at_period_end' : 'subscription_updated'
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
await db.user.update({
|
||||
where: {
|
||||
stripeSubscriptionId: subscription.id,
|
||||
},
|
||||
data: {
|
||||
stripePriceId: subscription.items.data[0].price.id,
|
||||
stripeCurrentPeriodEnd: currentPeriodEnd,
|
||||
plan: getPlanFromStripePriceId(subscription.items.data[0].price.id) ?? undefined,
|
||||
},
|
||||
});
|
||||
const updated = await db.user.findUnique({
|
||||
where: { stripeSubscriptionId: subscription.id },
|
||||
select: { id: true },
|
||||
});
|
||||
if (updated?.id) {
|
||||
await scoreUserLifecycle(
|
||||
updated.id,
|
||||
subscription.cancel_at_period_end ? 'subscription_canceled_at_period_end' : 'subscription_updated'
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'customer.subscription.deleted': {
|
||||
const subscription = event.data.object as Stripe.Subscription;
|
||||
|
||||
const updatedUser = await db.user.update({
|
||||
where: {
|
||||
stripeSubscriptionId: subscription.id,
|
||||
},
|
||||
const updatedUser = await db.user.update({
|
||||
where: {
|
||||
stripeSubscriptionId: subscription.id,
|
||||
},
|
||||
data: {
|
||||
stripeSubscriptionId: null,
|
||||
stripePriceId: null,
|
||||
stripeCurrentPeriodEnd: null,
|
||||
plan: 'FREE',
|
||||
},
|
||||
});
|
||||
|
||||
await scoreUserLifecycle(updatedUser.id, 'subscription_deleted');
|
||||
break;
|
||||
}
|
||||
plan: 'FREE',
|
||||
},
|
||||
});
|
||||
|
||||
await scoreUserLifecycle(updatedUser.id, 'subscription_deleted');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.json({ received: true });
|
||||
|
||||
Reference in New Issue
Block a user