Integrações

Stripe

Clientes, assinaturas, faturas, checkout e contestações do Stripe viram contatos e eventos que disparam automações.

Com a integração do Stripe, cada cliente vira contato e cada cobrança, assinatura ou contestação vira um evento que pode iniciar uma automação: um e-mail quando o pagamento falha, um lembrete quando o teste grátis está acabando, uma pesquisa quando alguém cancela.

#Crie a conexão

No painel, abra Integrações › Seu app e clique em Conectar no cartão do Stripe. A conexão tem a sua URL, que você cola no provedor, e mostra o passo a passo na própria tela.

URL da conexão (exemplo)
https://api.postal.so/integrations/crm/01a1c2d3-e4f5-7a6b-8c9d-0e1f2a3b4c5d/webhook

No Stripe, abra Desenvolvedores › Webhooks, clique em Adicionar destino, cole a URL e escolha os eventos da tabela abaixo. Depois, abra o destino, revele o Segredo de assinatura (whsec_…) e cole na conexão. O segredo fica criptografado e não aparece de novo.

Como a Postal confere

Cada requisição precisa do cabeçalho Stripe-Signature válido para o segredo e com no máximo 5 minutos. Sem ele, a resposta é 401 e nada muda.

As integrações de app contam no limite do plano (app_integrations). Fora do plano, os cartões aparecem bloqueados com o botão Fazer upgrade.

#Eventos

Todo evento leva também stripe_event_id, customer_id e livemode. Valores em dinheiro vêm na unidade da moeda (49.9 para R$ 49,90), com a moeda em maiúsculas (BRL).

Evento do StripeEvento na PostalQuandoPropriedades
checkout.session.completedstripe.checkout.session.completedCheckout concluídocheckout_session_id, amount, currency, mode, payment_status, subscription_id
checkout.session.async_payment_succeededstripe.checkout.session.async_payment_succeededPagamento assíncrono (boleto, Pix) aprovadoas do checkout
checkout.session.async_payment_failedstripe.checkout.session.async_payment_failedPagamento assíncrono recusado ou vencidoas do checkout
customer.createdstripe.customer.createdCliente criadocustomer_id, name, phone
customer.updatedstripe.customer.updatedCliente atualizadoas do cliente
customer.deletedstripe.customer.deletedCliente excluído (exclusão, veja abaixo)as do cliente
customer.subscription.createdstripe.customer.subscription.createdAssinatura criadasubscription_id, status, plan, price_id, product_id, amount, currency, interval, trial_end, current_period_end
customer.subscription.updatedstripe.customer.subscription.updatedAssinatura alterada (plano, status, cancelamento agendado)as da assinatura, mais cancel_at_period_end
customer.subscription.pausedstripe.customer.subscription.pausedAssinatura pausadaas da assinatura
customer.subscription.resumedstripe.customer.subscription.resumedAssinatura retomadaas da assinatura
customer.subscription.trial_will_endstripe.customer.subscription.trial_will_endTeste grátis acaba em 3 diasas da assinatura
customer.subscription.deletedstripe.customer.subscription.deletedAssinatura canceladaas da assinatura, mais cancellation_reason
invoice.paidstripe.invoice.paidFatura pagainvoice_id, invoice_number, amount, currency, status, billing_reason, plan, hosted_invoice_url, invoice_pdf
invoice.payment_failedstripe.invoice.payment_failedFalha no pagamento da faturaas da fatura, mais attempt_count e next_payment_attempt
invoice.upcomingstripe.invoice.upcomingPróxima fatura (dias antes da cobrança)as da fatura, mais amount_due e period_end
charge.dispute.createdstripe.charge.dispute.createdContestação abertadispute_id, charge_id, amount, currency, reason, status
charge.dispute.closedstripe.charge.dispute.closedContestação encerradaas da contestação

Outros eventos do Stripe são aceitos e ignorados.

#Qual contato

O contato é o cliente do Stripe, pelo e-mail que vem no próprio evento (o do cliente, customer_email da fatura ou customer_details.email do checkout). A Postal não chama a API do Stripe: quando o evento traz só o ID do cliente (como as assinaturas), vale o contato já ligado a esse ID por um evento anterior. Sem e-mail e sem contato ligado, o evento é pulado e aparece como “ignorado” no registro.

O nome do cliente vira nome e sobrenome do contato, e metadata.user_id (ou userId, external_id) vira o external_id: guarde nele o ID do usuário no seu app ao criar o cliente no Stripe.

Criando o cliente com o ID do seu app
await stripe.customers.create({
  email: '[email protected]',
  name: 'Fulano de Tal',
  metadata: { user_id: user.id },
})

Para o customer.deleted, a conexão diz o que fazer com o contato: só registrar o evento (padrão), descadastrar o contato (ele continua na audiência, sem receber marketing) ou excluir o contato (sem evento, já que o contato some). Uma exclusão nunca cria um contato que a Postal não tinha.

#Configurações da conexão

  • Eventos: só os marcados viram contato e evento; os outros são ignorados (a resposta ainda é 202).
  • Sincronizar o nome: atualiza nome e sobrenome do contato com o que vier do provedor.
  • Adicionar ao segmento e Inscrever no tópico: um segmento estático e um tópico para cada contato que chega.
  • Quando o usuário for excluído no app: só registrar, descadastrar ou excluir o contato.

Tudo que a conexão muda no contato leva a origem crm:<id da conexão> (last_change_source), e cada entrega aparece no registro da conexão, com o resultado de cada pessoa. Uma entrega repetida pelo provedor (mesmo ID) não é processada duas vezes.

#Dispare automações

Cada evento fica no contato com o nome stripe.invoice.payment_failed e as propriedades da tabela acima. Na tela da conexão, o botão Criar automação ao lado de cada evento abre uma automação nova com o gatilho Evento recebido já preenchido. Pelos endpoints de automações, o gatilho é {"type": "event", "event": "stripe.invoice.payment_failed"}.

Exemplo: quando a cobrança falha, mande um e-mail com o botão para a fatura ({{event.hosted_invoice_url}}) e, se depois de 3 dias não houver stripe.invoice.paid, um segundo aviso. Nos e-mails, as propriedades do evento entram como {{event.amount}} nos passos ou como variáveis do template ({{{amount}}}).

#Testar

Com a CLI do Stripe, dispare eventos de teste para o seu destino:

Terminal
stripe trigger customer.created
stripe trigger invoice.payment_failed

O contato aparece em Audiência e o evento em Eventos. No Stripe, cada entrega mostra a resposta da Postal (202 aceito, 401 assinatura inválida, 409 conexão pausada).

Evolução

A conexão com um clique (app do Stripe, sem copiar segredo) está nos planos. Por enquanto, o destino é criado à mão no Stripe.