ZH
测试版翻译

@core / billing

1.0.0 ▾
已验证MIT
GitHub

Stripe 订阅:结账、客户门户和幂等 Webhook(Drizzle)

代码9 个文件上下文约 633 个 tokenMCP stripe扫描通过

应用 .genpmignore 后将被注入的确切目录树。固定于

src/lib/billing/adapters/next.ts只读 · a8a5ac1
// Adaptador Next.js (App Router), Request/Response estándar:
//   app/billing/checkout/route.ts → export const POST = checkoutRoute;
//   app/billing/portal/route.ts   → export const POST = portalRoute;
//   app/billing/webhook/route.ts  → export const POST = webhookRoute;
import { getUserFromCookieHeader } from '../../auth/index.js';
import { createCheckoutSession, createPortalSession, handleStripeWebhook, WebhookSignatureError } from '../index.js';

const json = (body: unknown, status = 200) => Response.json(body, { status });

export async function checkoutRoute(req: Request): Promise<Response> {
  const user = await getUserFromCookieHeader(req.headers.get('cookie'));
  if (!user) return json({ error: 'unauthorized' }, 401);
  const { priceId } = (await req.json().catch(() => ({}))) as { priceId?: string };
  if (!priceId) return json({ error: 'priceId required' }, 400);
  const { origin } = new URL(req.url);
  return json(await createCheckoutSession({ user, priceId, successUrl: `${origin}/billing/success`, cancelUrl: `${origin}/pricing` }));
}

export async function portalRoute(req: Request): Promise<Response> {
  const user = await getUserFromCookieHeader(req.headers.get('cookie'));
  if (!user) return json({ error: 'unauthorized' }, 401);
  return json(await createPortalSession(user, `${new URL(req.url).origin}/account`));
}

export async function webhookRoute(req: Request): Promise<Response> {
  try {
    return json(await handleStripeWebhook(await req.text(), req.headers.get('stripe-signature')));
  } catch (e) {
    if (e instanceof WebhookSignatureError) return json({ error: e.message }, 400);
    throw e;
  }
}

举报 @core/billing

使用 GitHub 登录后才能举报包。