Add proper API docs page, fix Stripe lazy init, update docs links
This commit is contained in:
parent
467a97ae1c
commit
7f04789997
5 changed files with 419 additions and 14 deletions
|
|
@ -2,9 +2,15 @@ import { Router, Request, Response } from "express";
|
|||
import Stripe from "stripe";
|
||||
import { createProKey, revokeByCustomer } from "../services/keys.js";
|
||||
|
||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || "", {
|
||||
apiVersion: "2025-01-27.acacia" as any,
|
||||
});
|
||||
let _stripe: Stripe | null = null;
|
||||
function getStripe(): Stripe {
|
||||
if (!_stripe) {
|
||||
const key = process.env.STRIPE_SECRET_KEY;
|
||||
if (!key) throw new Error("STRIPE_SECRET_KEY not configured");
|
||||
_stripe = new Stripe(key, { apiVersion: "2025-01-27.acacia" as any });
|
||||
}
|
||||
return _stripe;
|
||||
}
|
||||
|
||||
const router = Router();
|
||||
|
||||
|
|
@ -13,7 +19,7 @@ router.post("/checkout", async (_req: Request, res: Response) => {
|
|||
try {
|
||||
const priceId = await getOrCreateProPrice();
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
const session = await getStripe().checkout.sessions.create({
|
||||
mode: "subscription",
|
||||
payment_method_types: ["card"],
|
||||
line_items: [{ price: priceId, quantity: 1 }],
|
||||
|
|
@ -37,7 +43,7 @@ router.get("/success", async (req: Request, res: Response) => {
|
|||
}
|
||||
|
||||
try {
|
||||
const session = await stripe.checkout.sessions.retrieve(sessionId);
|
||||
const session = await getStripe().checkout.sessions.retrieve(sessionId);
|
||||
const customerId = session.customer as string;
|
||||
const email = session.customer_details?.email || "unknown@docfast.dev";
|
||||
|
||||
|
|
@ -66,7 +72,7 @@ a { color: #4f9; }
|
|||
<div class="key" onclick="navigator.clipboard.writeText('${keyInfo.key}')" title="Click to copy">${keyInfo.key}</div>
|
||||
<p><strong>Save this key!</strong> It won't be shown again.</p>
|
||||
<p>10,000 PDFs/month • All endpoints • Priority support</p>
|
||||
<p><a href="/#endpoints">View API docs →</a></p>
|
||||
<p><a href="/docs">View API docs →</a></p>
|
||||
</div></body></html>`);
|
||||
} catch (err: any) {
|
||||
console.error("Success page error:", err.message);
|
||||
|
|
@ -83,7 +89,7 @@ router.post("/webhook", async (req: Request, res: Response) => {
|
|||
|
||||
if (webhookSecret && sig) {
|
||||
try {
|
||||
event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
|
||||
event = getStripe().webhooks.constructEvent(req.body, sig, webhookSecret);
|
||||
} catch (err: any) {
|
||||
console.error("Webhook signature verification failed:", err.message);
|
||||
res.status(400).json({ error: "Invalid signature" });
|
||||
|
|
@ -114,25 +120,25 @@ let cachedPriceId: string | null = null;
|
|||
async function getOrCreateProPrice(): Promise<string> {
|
||||
if (cachedPriceId) return cachedPriceId;
|
||||
|
||||
const products = await stripe.products.search({ query: "name:'DocFast Pro'" });
|
||||
const products = await getStripe().products.search({ query: "name:'DocFast Pro'" });
|
||||
let productId: string;
|
||||
|
||||
if (products.data.length > 0) {
|
||||
productId = products.data[0].id;
|
||||
const prices = await stripe.prices.list({ product: productId, active: true, limit: 1 });
|
||||
const prices = await getStripe().prices.list({ product: productId, active: true, limit: 1 });
|
||||
if (prices.data.length > 0) {
|
||||
cachedPriceId = prices.data[0].id;
|
||||
return cachedPriceId;
|
||||
}
|
||||
} else {
|
||||
const product = await stripe.products.create({
|
||||
const product = await getStripe().products.create({
|
||||
name: "DocFast Pro",
|
||||
description: "Unlimited PDF conversions via API. HTML, Markdown, and URL to PDF.",
|
||||
});
|
||||
productId = product.id;
|
||||
}
|
||||
|
||||
const price = await stripe.prices.create({
|
||||
const price = await getStripe().prices.create({
|
||||
product: productId,
|
||||
unit_amount: 900,
|
||||
currency: "usd",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue