Endpoint
Overview
Creates a Polar checkout session for DROP service subscription. Redirects to Polar checkout page.
Request
Requires authentication via Bearer token.
Query Parameters
Plan identifier: "pro-lite" or "pro"
Billing cycle: "monthly" or "yearly"
Response
Redirects to Polar checkout page (302 redirect).
Implementation Details
Code Reference
export async function GET(request: NextRequest) {
const corsResponse = handleCors(request)
if (corsResponse) return corsResponse
const blocked = await protectRoute(request, { requested: 2 })
if (blocked) return blocked
const auth = await requireAuth(request)
if ('error' in auth) return auth.error
const searchParams = request.nextUrl.searchParams
const plan = searchParams.get('plan')
const billingCycle = searchParams.get('billingCycle')
if (!plan || !billingCycle) {
return errorResponse('Missing plan or billingCycle', 400, request.headers.get('origin'))
}
const productId = PRODUCT_IDS[plan]?.[billingCycle]
if (!productId) {
return errorResponse('Invalid plan or billingCycle', 400, request.headers.get('origin'))
}
const user = await prisma.user.findUnique({
where: { id: auth.userId },
select: { id: true, email: true },
})
if (!user) {
return errorResponse('User not found', 404, request.headers.get('origin'))
}
const entitlement = await prisma.userServiceEntitlement.findUnique({
where: {
userId_service: {
userId: auth.userId,
service: 'DROP',
},
},
select: { polarCustomerId: true },
})
const metadata = {
plan,
billingCycle,
userId: user.id
}
let validCustomerId = null
if (entitlement?.polarCustomerId) {
try {
const response = await fetch(`https://api.polar.sh/v1/customers/${entitlement.polarCustomerId}`, {
headers: {
'Authorization': `Bearer ${process.env.POLAR_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
})
if (response.ok) {
validCustomerId = entitlement.polarCustomerId
}
} catch (error) {
}
}
const checkoutParams = new URLSearchParams({
products: productId,
metadata: JSON.stringify(metadata),
customerEmail: user.email,
...(validCustomerId && { customerId: validCustomerId })
})
const checkoutHandler = Checkout({
accessToken: process.env.POLAR_ACCESS_TOKEN!,
successUrl: `${process.env.NEXT_PUBLIC_APP_URL || 'https://nulldrop.xyz'}/settings?tab=premium&success=true`,
server: (process.env.POLAR_SERVER as "sandbox" | "production") || "production",
})
const modifiedRequest = new NextRequest(
`${request.url.split('?')[0]}?${checkoutParams.toString()}`,
request
)
return checkoutHandler(modifiedRequest)
}
Status Codes
Redirect to Polar checkout page
Missing or invalid plan/billingCycle parameters
Missing or invalid authentication token
Example Request
curl -X GET "https://auth.nullpass.xyz/api/polar/checkout?plan=pro&billingCycle=monthly" \
-H "Authorization: Bearer YOUR_TOKEN"
Available Plans
- pro-lite: Pro Lite plan
monthly: Monthly billing
yearly: Yearly billing
- pro: Pro plan
monthly: Monthly billing
yearly: Yearly billing
Environment Variables
Polar product ID for Pro Lite monthly
Polar product ID for Pro Lite yearly
Polar product ID for Pro monthly
Polar product ID for Pro yearly
POLAR_SERVER
string
default:"production"
Polar server: "sandbox" or "production"
App URL for success redirect (default: https://nulldrop.xyz)
Notes
- Existing Polar customer ID is reused if available
- Metadata includes plan, billingCycle, and userId
- Success URL redirects to app settings page
- Only works for DROP service