Planos e features
Declare o que cada plano inclui. O resto do app só pergunta se o cliente pode.
Uma feature é algo que você controla: mensagens, assentos, um modelo melhor. Um plano diz quanto de cada feature o cliente recebe e quanto custa.
import { feature, plan } from "dunas"
export const messages = feature({ id: "messages", type: "metered" })
export const seats = feature({ id: "seats", type: "metered" })
export const proModels = feature({ id: "pro_models", type: "boolean" })
export const free = plan({
id: "free",
default: true,
includes: [messages({ limit: 100 }), seats({ limit: 1, reset: "never" })],
})
export const pro = plan({
id: "pro",
price: { amountInCents: 4_990, interval: "month" },
includes: [messages({ limit: 5_000 }), seats({ limit: 10, reset: "never" }), proModels()],
})Dois tipos de feature
Com limite (metered) conta o uso. O limite é um número ou "unlimited", e o uso volta a zero todo mês. Mude com reset: day, week, month, year ou never. Assentos, por exemplo, não zeram.
Liga e desliga (boolean) só diz se o plano tem ou não tem.
O plano padrão
Quem nunca assinou nada está no plano marcado com default: true. Ele precisa ser grátis. Quando uma assinatura paga é cancelada, o cliente volta para ele.
Grupos e add-ons
Planos do mesmo group se substituem: assinar o Pro tira o cliente do grátis. Todo plano está no grupo "base" se você não disser outro.
Planos em grupos diferentes se somam. É assim que você faz um add-on:
export const extraSeats = plan({
id: "extra_seats",
group: "seats",
price: { amountInCents: 1_990, interval: "month" },
includes: [seats({ limit: 5, reset: "never" })],
})Um cliente no Pro com esse add-on tem 15 assentos.
Tudo tipado
Os ids dos planos e das features viram tipos. Um id escrito errado não compila, em nenhum lugar do app.
Todas as opções estão na referência.