S

Stripe

OAuth (Connect) · cartão, recorrência nativa

Stripe Connect (OAuth): você autoriza uma vez e os eventos de todas as contas conectadas chegam num endpoint único. Recorrência nativa, cartão.

Use o modo LIVE — não um Sandbox. O OAuth do Connect (fluxo legado) não casa com a chave de um sandbox: a troca de token retorna 401. Em contas novas o antigo "test mode" virou Sandbox; mesmo assim, conecte em live.

Conectar

  1. Ative o Connect (Connect → Overview → Standard/OAuth) e aceite o termo de plataforma.
  2. Settings → Connect → OAuth: copie o client_id (ca_…) e adicione o Redirect URI https://indicasaas.com/oauth/stripe/callback.
  3. Developers → API keys: copie a Secret key (sk_live_…).
  4. Developers → Webhooks: crie um endpoint https://indicasaas.com/webhooks/stripe, estilo Snapshot, ouvindo Connected accounts, com os 6 eventos da tabela abaixo. Copie o signing secret (whsec_…).
  5. Configure os 3 como secrets do Worker: STRIPE_CLIENT_ID, STRIPE_SECRET_KEY, STRIPE_CONNECT_WEBHOOK_SECRET — todos da mesma conta, no mesmo modo.
  6. No painel → Meu SaaS → Instalação → Gateways → Stripe → Conectar → autorize.

Passe o ref no checkout

O valor do ref é o click_id que o afs.js persistiu (AFS.getRef()). Anexe-o no client_reference_id (Checkout) e/ou subscription_data.metadata.aff_ref (assinatura) ao criar a cobrança.

const ref = AFS.getRef(); // vindo do front

const session = await stripe.checkout.sessions.create({
  mode: 'subscription',            // ou 'payment'
  line_items: [/* ... */],
  client_reference_id: ref,        // 1ª venda
  subscription_data: {             // renovações mantêm a atribuição
    metadata: { aff_ref: ref },
  },
  // opcional p/ "apenas novos clientes":
  metadata: { aff_new: '1' },
});
Em assinaturas, a 1ª cobrança só semeia a atribuição; a comissão vem em cada invoice.paid — evita comissão dobrada na 1ª cobrança.

Eventos

EventoO que faz
checkout.session.completed1ª venda (one-off) ou semeia a assinatura
invoice.paid / invoice.payment_succeededcobrança recorrente → comissão
charge.refundedreembolso → clawback
charge.dispute.createdchargeback → clawback
customer.subscription.deletedcancelamento (churn)

Problemas comuns

gw_error=exchange (401) na conexão = o client_id e a secret key são de contas diferentes (ou um é de sandbox). Garanta que ambos vêm da mesma conta, em live.