Leyla mağazadan kitablar alır və «Prowid Shop Plus» istəyir: ayda 9.90 AZN-ə pulsuz çatdırılma. O, hər ay «Ödə» düyməsinə basmayacaq: pul imtina edənə qədər özü çıxılmalıdır. Bu — abunəlikdir və onun üç çətinliyi var: müntəzəm çıxarışlar, tarifin dəyişdirilməsi və ləğvi, bəzən keçməyən kartlar. Bütün bunları Stripe Billing öz üzərinə götürür, bizə isə giriş vəziyyətini öz bazamızda saxlamaq qalır.
Abunəliyin obyektləri
Product — nə satırıq («Prowid Shop Plus»), Price — nə qədər və nə qədər tez-tez (9.90 AZN, recurring.interval: 'month'), Customer — alıcı. Subscription — alıcı ilə qiymət arasındakı müqavilə: «hər ay 9.90 AZN çıx». Hər dövrdə Stripe Invoice (hesab) buraxır və onu PaymentIntent vasitəsilə ödəyir (dərs 041). Bənzətmə: idman zalı abunəliyi: müqavilə birdir, hesab isə hər ay gəlir.
Stripe öz obyektlərini saxlayır, sizin baza isə vəziyyətin surətini: kim abunə olub və hansı tarixə qədər. Tətbiq Stripe-ı yox, öz bazanızı oxuyur.
Qiymət və abunə rejimində Checkout
Product və təkrarlanan Price bir dəfə yaradılır, Dashboard-da və ya skriptlə:
// scripts/create-plus.js (run once)
import { stripe } from '../src/stripe.js';
const product = await stripe.products.create({ name: 'Prowid Shop Plus' });
const price = await stripe.prices.create({
product: product.id,
currency: 'azn',
unit_amount: 990, // 9.90 AZN every month
recurring: { interval: 'month' },
});
console.log(price.id); // price_... -> PLUS_PRICE_ID in .envQiymətin id-sini .env-də PLUS_PRICE_ID kimi saxlayın. Alıcıya Customer lazımdır: onu ilk abunəlikdə yaradıb stripeCustomerId-ni User-də yadda saxlayırıq. Sonra mode: 'subscription' ilə Checkout Session:
// src/billing.js
import { stripe } from './stripe.js';
import { prisma } from './db.js';
import { handleOnce } from './idempotent.js';
export async function startSubscription(req, res) {
const user = req.user; // from your auth middleware, never from the body
let customerId = user.stripeCustomerId;
if (!customerId) {
const customer = await stripe.customers.create(
{ email: user.email, metadata: { userId: String(user.id) } },
{ idempotencyKey: `user-${user.id}-customer` },
);
customerId = customer.id;
await prisma.user.update({
where: { id: user.id },
data: { stripeCustomerId: customerId },
});
}
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
customer: customerId,
line_items: [{ price: process.env.PLUS_PRICE_ID, quantity: 1 }],
success_url: `${process.env.APP_URL}/plus/thanks`,
cancel_url: `${process.env.APP_URL}/plus`,
});
res.json({ url: session.url });
}