Tutoriais

Habilitar pagamento com Stripe

Com esse tutorial você será capaz habilitar o pagamento das assinaturas do seu projeto com stripe.


Passo a Passo

JustLaunch utiliza Stripe como gateway de pagamento para cobrar assinatura. O template já vem todo configurado para utilização da stripe como gateway de pagamento e além de fazer todo o gerenciamento de estado da assinatura, ou seja automaticamente ficamos ouvindo os eventos da stripe para verificar se o usuário - assinou, cancelou, mudou de assinatura entre outras funcionalidade, só precisamos habilitar em nosso código, siga as instruções abaixo para habilitar a stripe como gateway de pagamento.

Crie uma conta no Stripe

Precisamos criar um conta no stripe para obter as credenciais necessárias para habilitar o gateway de pagamento. Crie uma conta no Stripe

Home do stripe

Após a criação de uma conta no stripe você sera capaz de visualizar acessar a dashboard da stripe

Dashboard do stripe

Adicione no .ENV

Acesse o menu desenvolvedores e logo após o menu de API key

API KEY

Adicione no seu .env em STRIPE_KEY a API key Chave secreta que está na stripe e mude para true a váriavel USE_STRIPE

USE_STRIPE=true
STRIPE_KEY= {Chave secreta}

Adicione Back-end no arquivo serverless.yml

STRIPE_API_KEY: {Chave secreta}

Configure o webhook na stripe

Acesse o menu desenvolvedores e logo após o menu de webhook

Webhook

Clique em adicionar um novo endpoint e você será direcionado para tela abaixo

Tela de eventos

Após entrar escolha os eventos que seu webhook vai ficar escultando e escolha somente esses -> customer.subscription.created, customer.subscription.deleted, customer.subscription.pending_update_applied , customer.subscription.pending_update_expired, customer.subscription.resumed e customer.subscription.updated

Tela de eventoss

E adicione a url do dominio do seu front-end + api/stripe/webhook, veja o exemplo abaixo

Se estiver utilizando back-end separado do front-end

Se você ainda não tem a url do Microsserviço de usuário, Acesse o tutorial de autenticação e vá para sessão extra para realizar o deploy do Microsserviço de usuário e obter a url do serviço.

Url do Webhook

Após configurar o webhook você terá acesso ao Segredo da assinatura clique em revelar

Secret do Webhook

Após revelar o segredo da assinatura copie e adicione no arquivo .env.local do seu Front-end

STRIPE_WEBHOOK_SECRET: {Segredo da assinatura}

Se estiver utilizando back-end separado do front-end

Após revelar o segredo da assinatura copie e adicione no arquivo serverless.yml do Back-end

STRIPE_WEBHOOK_KEY: {Segredo da assinatura}

Criar o produto de assinaturas

Na nossa landing page temos a opção de colocar 2 assinaturas como podemos ver na imagem abaixo

Pricing

Então na stripe vamos precisar criar 2 produtos um Starter e outro Pro

Modo Teste

Se você tiver utilizando o modo teste, quando você transferir para o modo produção na stripe deve recriar seus produtos no modo produção também.

Para criar esses produtos na stripe devemos clicar no menu chamado mais e entrar no painel Catálogo de produtos

Menu para produtos

Após entrar no Catálogo de produtos podemos criar o produto no modelo recorrente ou avulso

Catálago de produtos

Clique em adicionar produto

Produto

Preencha as informações do seu produto, Escolha um preço, o Modelo recorrente (mensal ou anual) ou Avulso e o Nome tem que ser Starter ou Pro

Adicionar Produto

Repita o mesmo procedimento para o outro nome de plano ou produto e ao final você terá como resultado dois produtos Starter e Pro

Starter & Pro

Se estiver utilizando back-end separado do front-end

Pule para Back-end(opcional) e siga as instruções e depois volte para seção front-end

Front-end

Vamos precisar adicionar a sessão do usuário na landing page para verificar se o usuário está logado para conseguir alterar o estado da assinatura dele para isso vamos adicionar o código abaixo e trocar outra linha de código.

As alterações estão com uma -> para você conseguir identificar o que precisa alterar na sua landing page para habilitar a sessão.

import Providers from '@/providers/Providers';
import {
  CallToAction,
  Faq,
  Features,
  Footer,
  Header,
  Hero,
  Problems,
  Stats,
  Testimonials,
  Pricing,
} from '../shared/@JustLaunch/components/LandingPage';
import { useLandingPageInternationalization } from '../shared/@JustLaunch/hooks/contents/useLandingPageInternationalization';
-> import { nextAuthOptions } from '../api/auth/[...nextauth]/auth';
-> import { getServerSession } from 'next-auth';

export default async function LandingPage() {
 -> const session = await getServerSession(nextAuthOptions);
  const {
    headerIntl,
    heroIntl,
    problemsIntl,
    footerIntl,
    callToActionIntl,
    statsIntl,
    testimonialsIntl,
    faqsIntl,
    pricingIntl,
    featuresIntl,
  } = await useLandingPageInternationalization();

  return (
    <>
      <Providers>
       -> <Header intl={headerIntl} session={session} />
        <Hero intl={heroIntl} />
        <Problems intl={problemsIntl} />
        <Features intl={featuresIntl} />
        <Testimonials intl={testimonialsIntl} />
        <Stats intl={statsIntl} />
        <Pricing intl={pricingIntl} />
        <Faq intl={faqsIntl} />
        <CallToAction intl={callToActionIntl} />
        <Footer intl={footerIntl} />
      </Providers>
    </>
  );
}

Testar assinatura ou produto avulso com cartão de teste

Para confirmar que sua integração está funcionando corretamente, simule transações sem mover nenhum dinheiro usando valores especiais no modo de teste.

Os cartões de teste permitem simular vários cenários:

Pagamentos sucedidos por marca ou país do cartão Erros de cartão devidos a pagamentos recusados, fraudes ou dados inválidos Contestações e reembolsos Autenticação com 3D Secure e PINs

Confira os cartões de teste da stripe aqui.

Back-end (Opcional)

Vamos precisar retirar os comentários de algumas linhas então copie e cole o código abaixo no arquivo CreateUsersUseCase

import { IAuthService } from '@domain/contracts/infrastructures/IAuthService';
import { IPaymentGatewayService } from '@domain/contracts/infrastructures/IPaymentGatewayService';
import { IUsersRepository } from '@domain/contracts/infrastructures/IUsersRepository';
import { ICreateUsersUseCase } from '@domain/contracts/usecases/ICreateUsersUseCase';
import { RequestToCreateUsersDTO } from '@domain/dtos/RequestToCreateUsersDTO';
import { User } from '@domain/entities/User';
import { SubscriptionStatus } from '@domain/enums/SubscriptionStatus';
import { ApplicationResult, ApplicationResultSuccess } from '@kernelsoftware/shared';
import { ILogger } from '@kernelsoftware/shared/dist/domain/contracts/infrastructure/ILogger';
import { buildReferralId } from '@utils/buildReferralId';
import { inject, injectable } from 'inversify';

@injectable()
export class CreateUsersUseCase implements ICreateUsersUseCase {
  className: string;

  constructor(
    @inject('Logger')
    private logger: ILogger,
    @inject('AuthService')
    private authService: IAuthService,
    @inject('PaymentGatewayService')
    private paymentGatewayService: IPaymentGatewayService,
    @inject('UsersRepository')
    private usersRepository: IUsersRepository<User>
  ) {
    this.className = 'CreateUsersUseCase';
  }

  async execute(data: RequestToCreateUsersDTO): Promise<ApplicationResult<User>> {
    const context = `${this.className}.execute`;

    this.logger.info('Start execute', {
      email: data.email,
      name: data.name,
      context,
    });

    const authResult = await this.authService.signUp(data);

    if (authResult.isError) {
      this.logger.error('Error on execute - AuthService', authResult.errorMessage, {
        context,
      });
      return authResult;
    }

    const uuid = User.generateId();

    const paymentGatewayResult = await this.paymentGatewayService.createCustomer({
      ...data,
      userId: uuid,
      tenantId: authResult.data,
    });

    if (paymentGatewayResult.isError) {
      this.logger.error('Error on execute - PaymentGatewayService', paymentGatewayResult.errorMessage, {
        context,
      });

      await this.authService.deleteUser(authResult.data);

      return paymentGatewayResult;
    }

    const userDomain = User.fromPlain(User, {
      id: uuid,
      email: data.email,
      name: data.name,
      phone: data.phone,
      subscriptionStatus: SubscriptionStatus.PENDING,
      tenantId: authResult.data,
      referralId: buildReferralId(),
      customerId: paymentGatewayResult.data,
    });

    const result = await this.usersRepository.upsert(userDomain);
    if (result.isError) {
      this.logger.error('Error on execute - AuthService', result.errorMessage, {
        context,
      });

      await this.authService.deleteUser(authResult.data);
      await this.paymentGatewayService.deleteCustomer(paymentGatewayResult.data);

      return result;
    }

    this.logger.info('Successful execution', {
      context,
    });
    return new ApplicationResultSuccess(result.data);
  }
}

Previous
Habilitar autenticação de usuário