(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).
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"}
}'| Campo | O que é |
|---|---|
kind | payment (por omissão) ou subscription. |
subscription.interval | De quanto em quanto tempo se cobra: week, month, quarter, half_year ou year. |
subscription.cycles | Quantos 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 com | Como se cobram os ciclos seguintes |
|---|---|
| Cartão | Sozinho, no cartão do comprador, pelo Stripe, no dia de cada ciclo. |
| Multicaixa Express, referência, BAI Paga | Estes 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
| Acontece | Estado | Evento |
|---|---|---|
| O primeiro ciclo é pago | active | subscription.created |
| Um ciclo seguinte é pago | active | subscription.renewed |
| O ciclo acabou sem a renovação paga | past_due (o acesso mantém-se, e ainda se pode pagar) | subscription.past_due |
| Passaram cinco dias de tolerância sem pagamento | expired, com end_reason unpaid | subscription.cancelled |
| Acabaram os ciclos contratados | expired, com end_reason completed | subscription.cancelled |
| Cancelada no fim do ciclo | active com cancel_at_period_end até current_period_end, depois cancelled | subscription.cancelled, logo no pedido |
| Cancelada já | cancelled | subscription.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:
# 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
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 pagoEm 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.