Payments
env.PAYMENTS lets your app charge its own customers through Stripe — one-off payments, subscriptions, a hosted customer portal, and signature-verified webhooks. It's a thin, ready-wired Stripe client; you supply your Stripe keys and it handles the calls.
This is for billing your app's users. It's separate from how Cloudrizz bills you for your plan (see pricing).
Setup: your Stripe keys
Set these as app environment variables (via set_app_env):
STRIPE_SECRET_KEY— required for all calls. (ASTRIPE_SECRET_KEY_TESTis used automatically on non-production deploys if set.)STRIPE_WEBHOOK_SECRET— required only if you verify webhooks.
Checkout
Create a Checkout session and redirect the user to session.url:
// api/checkout.js
export default {
async fetch(request, env, ctx) {
const user = await env.AUTH.getUser(request);
if (!user) return new Response("Unauthorized", { status: 401 });
const session = await env.PAYMENTS.checkout.create({
mode: "subscription",
line_items: [{ price: "price_123", quantity: 1 }],
success_url: "https://your-app.com/success",
cancel_url: "https://your-app.com/pricing",
customer_email: user.email,
});
return Response.json({ url: session.url });
},
};Subscriptions & access checks
There's no separate entitlement store — check access by reading the customer's subscriptions:
const subs = await env.PAYMENTS.subscriptions.list({ customer: customerId });
const hasAccess = subs.data?.some((s) => s.status === "active");Also available:
customers.create / retrieve / updatesubscriptions.list / retrieve / cancelpaymentIntents.create / retrieveportal.create({ customer, return_url })— a hosted billing portal URL.
Webhooks
Add a route for Stripe events and verify the signature — verification throws on a bad signature or replay:
// api/webhooks/stripe.js
export default {
async fetch(request, env, ctx) {
const event = await env.PAYMENTS.webhook.verify(request);
if (event.type === "checkout.session.completed") {
// grant access, record the customer id, etc.
}
return new Response("ok");
},
};Point your Stripe webhook endpoint at https://your-app.com/api/webhooks/stripe and set STRIPE_WEBHOOK_SECRET.