Entrar no painel
Índice

(08) Receber pagamentos

Subscrições

Cobrar todos os meses: a sessão em modo subscrição, as renovações e o cancelamento.

A sessão em modo subscrição

Uma subscrição nasce de uma sessão de checkout como as outras, com kind igual a subscription e o plano em subscription. O amount é o preço de cada ciclo. Quando o comprador paga o primeiro ciclo, a subscrição fica ativa e recebes subscription.created (além do payment.succeeded desse pagamento).

Terminal
curl -s "$SPOLLY_API_URL/v1/checkout/sessions" \
  -H "Authorization: Bearer $SPOLLY_SECRET_KEY" \
  -H "Idempotency-Key: assinatura-cliente-77" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "subscription",
    "subscription": {"interval": "month", "cycles": 12},
    "amount": 500000,
    "currency": "AOA",
    "description": "Plano mensal",
    "success_url": "https://loja.exemplo.ao/obrigado",
    "customer": {"email": "cliente@exemplo.ao"},
    "metadata": {"cliente_id": "77"}
  }'
CampoO que é
kindpayment (por omissão) ou subscription.
subscription.intervalDe quanto em quanto tempo se cobra: week, month, quarter, half_year ou year.
subscription.cyclesQuantos ciclos, ao todo, de 1 a 1000. Sem ele, renova até ser cancelada.

O dia da cobrança é o do primeiro pagamento: uma subscrição mensal paga a 31 renova no último dia dos meses mais curtos, e volta ao 31 quando o mês o tem. Os avisos das renovações vão para o email do comprador, e a sessão paga passa a trazer o id da subscrição em subscription.id.

Como renova

Pago comComo se cobram os ciclos seguintes
CartãoSozinho, no cartão do comprador, pelo Stripe, no dia de cada ciclo.
Multicaixa Express, referência, BAI PagaEstes métodos não cobram sozinhos. Antes de cada ciclo, o comprador recebe um email com um link de pagamento de uso único, que abre uma sessão de checkout já preenchida; paga como pagou da primeira vez.

Cada ciclo pago é um pagamento normal: tem o seu payment.succeeded, o seu recibo, entra no teu saldo, e leva a subscrição ao ciclo seguinte com subscription.renewed.

Os estados e os eventos

AconteceEstadoEvento
O primeiro ciclo é pagoactivesubscription.created
Um ciclo seguinte é pagoactivesubscription.renewed
O ciclo acabou sem a renovação pagapast_due (o acesso mantém-se, e ainda se pode pagar)subscription.past_due
Passaram cinco dias de tolerância sem pagamentoexpired, com end_reason unpaidsubscription.cancelled
Acabaram os ciclos contratadosexpired, com end_reason completedsubscription.cancelled
Cancelada no fim do cicloactive com cancel_at_period_end até current_period_end, depois cancelledsubscription.cancelled, logo no pedido
Cancelada jácancelledsubscription.cancelled

O objeto de cada evento, com todos os campos, está na referência dos eventos. Dá acesso ao teu cliente enquanto a subscrição estiver active ou past_due, e até ao current_period_end.

Ler, cancelar e a página do cliente

O id da subscrição (sub_...) chega no subscription.created. Com ele:

Terminal
# Ler
curl -s "$SPOLLY_API_URL/v1/subscriptions/sub_..." \
  -H "Authorization: Bearer $SPOLLY_SECRET_KEY"

# Cancelar no fim do ciclo pago (com {"at_period_end": false}, termina já)
curl -s -X POST "$SPOLLY_API_URL/v1/subscriptions/sub_.../cancel" \
  -H "Authorization: Bearer $SPOLLY_SECRET_KEY" \
  -H "Idempotency-Key: cancelar-sub-77"

# Um link de uso único para a página do cliente
curl -s -X POST "$SPOLLY_API_URL/v1/subscriptions/sub_.../portal" \
  -H "Authorization: Bearer $SPOLLY_SECRET_KEY" \
  -H "Idempotency-Key: portal-77-$(date +%s)"

Em Go

Go
doze := 12
sessao, err := cliente.CreateCheckoutSession(ctx, &spolly.CheckoutSessionParams{
	Amount: 500000, Currency: spolly.AOA, Description: "Plano mensal",
	Kind:         spolly.KindSubscription,
	Subscription: &spolly.SubscriptionPlan{Interval: spolly.IntervalMonth, Cycles: &doze}, // Cycles nil: até cancelar
})

// Depois do primeiro pagamento (chega subscription.created, com o id):
sub, err := cliente.GetSubscription(ctx, idDaSubscricao)
link, err := cliente.CreateSubscriptionPortalLink(ctx, sub.ID) // mandar link.URL ao cliente
sub, err = cliente.CancelSubscription(ctx, sub.ID, nil)        // no fim do ciclo pago

Em JavaScript

JavaScript
await spolly.createCheckoutSession({
  amount: 500000, currency: "AOA", description: "Plano mensal",
  kind: "subscription",
  subscription: { interval: "month", cycles: 12 }, // sem cycles: até cancelar
});

// Depois do primeiro pagamento (chega subscription.created, com o id):
const sub = await spolly.getSubscription(idDaSubscricao);
const { url } = await spolly.createSubscriptionPortalLink(sub.id); // mandar ao cliente
await spolly.cancelSubscription(sub.id); // no fim do ciclo pago; { at_period_end: false } termina já

A página do cliente é onde o teu cliente cancela, muda o método do próximo ciclo e vê os recibos, sem criar conta. O link da rota portal serve uma vez e vale 24 horas; manda-o ao cliente (no teu site, num botão "Gerir a subscrição"). O cliente também o pode pedir por email, na própria página. Cada pedido dá um link novo.

Um cancelamento nunca devolve dinheiro

Cancelar no fim do ciclo deixa o cliente usar o que pagou, e não há mais cobranças. Para devolver um ciclo, faz um estorno do pagamento dele.