diff --git a/backoffice/src/stripe/index.ts b/backoffice/src/stripe/index.ts new file mode 100644 index 0000000..71f3586 --- /dev/null +++ b/backoffice/src/stripe/index.ts @@ -0,0 +1,2 @@ +export * from './stripe.module'; +export * from './stripe.service'; diff --git a/backoffice/src/stripe/stripe.module.ts b/backoffice/src/stripe/stripe.module.ts new file mode 100644 index 0000000..1376f19 --- /dev/null +++ b/backoffice/src/stripe/stripe.module.ts @@ -0,0 +1,11 @@ +import { Module, Global } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { StripeService } from './stripe.service'; + +@Global() +@Module({ + imports: [ConfigModule], + providers: [StripeService], + exports: [StripeService], +}) +export class StripeModule { } diff --git a/backoffice/src/stripe/stripe.service.ts b/backoffice/src/stripe/stripe.service.ts new file mode 100644 index 0000000..3f822ff --- /dev/null +++ b/backoffice/src/stripe/stripe.service.ts @@ -0,0 +1,62 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import Stripe from 'stripe'; + +@Injectable() +export class StripeService implements OnModuleInit { + private stripe: Stripe; + + constructor(private configService: ConfigService) { } + + onModuleInit() { + const secretKey = this.configService.get('STRIPE_SECRET_KEY'); + if (!secretKey) { + console.warn('STRIPE_SECRET_KEY not configured'); + return; + } + this.stripe = new Stripe(secretKey, { apiVersion: '2024-11-20.acacia' }); + } + + getClient(): Stripe { return this.stripe; } + + async createCustomer(email: string, name: string) { + return this.stripe.customers.create({ email, name }); + } + + async createSubscription(customerId: string, priceId: string) { + return this.stripe.subscriptions.create({ + customer: customerId, + items: [{ price: priceId }], + payment_behavior: 'default_incomplete', + expand: ['latest_invoice.payment_intent'], + }); + } + + async cancelSubscription(subscriptionId: string) { + return this.stripe.subscriptions.cancel(subscriptionId); + } + + async listSubscriptions(customerId: string) { + return this.stripe.subscriptions.list({ customer: customerId, status: 'all' }); + } + + async createCheckoutSession(customerId: string, priceId: string, successUrl: string, cancelUrl: string) { + return this.stripe.checkout.sessions.create({ + customer: customerId, + payment_method_types: ['card'], + line_items: [{ price: priceId, quantity: 1 }], + mode: 'subscription', + success_url: successUrl, + cancel_url: cancelUrl, + }); + } + + async createBillingPortalSession(customerId: string, returnUrl: string) { + return this.stripe.billingPortal.sessions.create({ customer: customerId, return_url: returnUrl }); + } + + constructWebhookEvent(body: Buffer, signature: string): Stripe.Event { + const secret = this.configService.get('STRIPE_WEBHOOK_SECRET')!; + return this.stripe.webhooks.constructEvent(body, signature, secret); + } +}