Integracao Stripe

Pagamentos avulsos com Checkout Sessions, PaymentIntent e webhooks.

A integracao Stripe gera pagamentos avulsos (one-time payments) usando Checkout Sessions e PaymentIntents. Diferente do Stripe Billing (assinaturas recorrentes), esta integracao e para vendas pontuais como e-commerce, doacoes ou servicos avulsos.

Stripe Service

// apps/api/src/integrations/stripe/stripe.service.ts
import Stripe from 'stripe';

export class StripeService {
  private stripe: Stripe;

  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
      apiVersion: '2024-06-20',
    });
  }

  async createCheckoutSession(params: {
    lineItems: Stripe.Checkout.SessionCreateParams.LineItem[];
    successUrl: string;
    cancelUrl: string;
    metadata?: Record<string, string>;
  }): Promise<string> {
    const session = await this.stripe.checkout.sessions.create({
      mode: 'payment',
      payment_method_types: ['card'],
      line_items: params.lineItems,
      success_url: params.successUrl,
      cancel_url: params.cancelUrl,
      metadata: params.metadata,
    });
    return session.url!;
  }

  async createPaymentIntent(params: {
    amount: number; // em centavos
    currency?: string;
    metadata?: Record<string, string>;
  }): Promise<{ clientSecret: string }> {
    const intent = await this.stripe.paymentIntents.create({
      amount: params.amount,
      currency: params.currency || 'brl',
      metadata: params.metadata,
    });
    return { clientSecret: intent.client_secret! };
  }
}

Webhook handler

// apps/api/src/integrations/stripe/stripe.webhook.ts
import Stripe from 'stripe';

export async function handleStripeWebhook(req: Request, res: Response) {
  const sig = req.headers['stripe-signature'] as string;
  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

  let event: Stripe.Event;
  try {
    event = stripe.webhooks.constructEvent(
      req.body, // raw body
      sig,
      process.env.STRIPE_WEBHOOK_SECRET!
    );
  } catch (err) {
    return res.status(400).json({ error: 'Webhook signature verification failed' });
  }

  switch (event.type) {
    case 'checkout.session.completed': {
      const session = event.data.object as Stripe.Checkout.Session;
      console.log('Pagamento confirmado:', session.id);
      // Atualizar pedido, enviar email, etc.
      break;
    }
    case 'payment_intent.succeeded': {
      const intent = event.data.object as Stripe.PaymentIntent;
      console.log('PaymentIntent succeeded:', intent.id);
      break;
    }
    case 'payment_intent.payment_failed': {
      const intent = event.data.object as Stripe.PaymentIntent;
      console.log('Pagamento falhou:', intent.last_payment_error?.message);
      break;
    }
  }

  res.json({ received: true });
}

// Registrar rota (IMPORTANTE: usar raw body)
app.post('/api/webhooks/stripe', express.raw({ type: 'application/json' }), handleStripeWebhook);

Variaveis de ambiente

VariavelDescricao
STRIPE_SECRET_KEYChave secreta da API (sk_test_... ou sk_live_...)
STRIPE_PUBLISHABLE_KEYChave publica para o frontend (pk_test_...)
STRIPE_WEBHOOK_SECRETSecret do webhook (whsec_...)